おはようございます。
テーブルA:商品コード
商品名
商品単価
テーブルB:商品コード
日付
売上数量
のテーブルがあり、
フォームA:テキスト1(商品コード
テキスト2(商品名
テキスト3(商品単価
データグリッド1(日付・売上数量
のフォームがあります。
テキストAに商品コードを打つとSQLでテキスト2とテキスト3に商品名と商品単価、
データグリッドに日付と売上数量が表示されるように記述したのですが。(下記)
テキスト2とテキスト3までは表示されて、データグリッドには表示されませんでした。
あと、データグリッドの中身を編集、追加してやりたいのですが、
OPENメソッドの引数に直でコネクションを指定したせいか、データグリッドの編集もできません。
SQLでデータを取得しなければ編集はできるのですが・・・
どう対処していいのか教えていただけたらと思っています。
(SQLサーバーを使用しています)
Private Sub Syohin_Cd_LostFocus()
Con1.Open
'定義
Dim RS As New ADODB.Recordset
Dim strSQL As String
'テーブルAのSQL記述
strSQL = "SELECT * FROM M1_SYOHIN_TBL WHERE M1_SYOHIN_CD = '" & Me.Syohin_Cd & "'"
RS.Open strSQL, CN
'テキスト2と3にデータを送る
Set Me.Syohin_Nm.DataSource = RS
Set Me.Syohin_Tn.DataSource = RS
Me.Syohin_Nm.DataField = "M1_SYOHIN_NM"
Me.Syohin_Tn.DataField = "M1_TANI1_CD"
RS.Close
'テーブルBのSQL記述
strSQL = "SELECT * FROM M2_TENKAI_TBL WHERE M2_SYOHIN_CD = '" & Me.Syohin_Cd & "'"
RS.Open strSQL, CN
Set Me.Tenkai.DataSource = RS
RS.Close
Con1.Close
End Sub
こんちは。
DataGridコントロールを使われているならADO データ (ADODC) コントロールを
使用していますよね?提示されたプログラムを拝見するとDataGridコントロールの
DataSourceに直接検索結果を設定しているだけに見えるのですが?
通常DataGridコントロールを使用するならADO データ (ADODC) コントロールを
使用してADO データ (ADODC) コントロールのDataSourceを書き換えます。
ADO データ (ADODC) コントロールのヘルプを参照してください。
JINさん:
> > テキストAに商品コードを打つとSQLでテキスト2とテキスト3に商品名と商品単価、
DataFormatプロパティを利用するような場合や、あるいは、そのRecordsetを
開き続けておくような場合には、TextBoxの DataSource が利用されますが、
今回のように、単に値を表示したいだけなのであれば、
Me.Syohin_Nm.Text = RS.Collect("M1_SYOHIN_NM") & ""
のように、Textプロパティに、値を直接送り込むのが一般的かと思います。
> > テキスト2とテキスト3までは表示されて、データグリッドには表示されませんでした。
データグリッドに割り当てるまでは良いですが、そのあと、
せっかくのRecordsetを閉じてしまっているからだと思います。
例えば、
Set Me.Tenkai.DataSource = RS
MsgBox "TEST"
RS.Close
のように、間に何か処理をおくと、(Closeされるまでは)表示されると思います。
データグリッドは、複数の行データを保持する関係上、元のレコードセットを
開き続けておく必要がありますので、この場合は、Closeはせずに、
Set Me.Tenkai.DataSource = RS
Set RS = Nothing
と変えてください。これならば表示されると思います。
なお、この時には Connection もCloseしないで下さい。DBとの接続が
切り離されてしまうため、やはり、データグリッドに表示されなくなります。
もし、Connectionを切り離したい場合は、
RS.CursorLocation = adUseClient
RS.Open strSQL, Con1, adOpenStatic, adLockBatchOptimistic
Set RS.ActiveConnection = Nothing
Con1.Close
Set Me.DataGrid1.DataSource = RS
Set RS = Nothing
のように、「静的バッチカーソル」モードを利用してください。
このモードであれば、RecordsetをOpenしたままDBを切断できます。
> > OPENメソッドの引数に直でコネクションを指定したせいか、データグリッドの編集もできません。
「RS.LockType が adLockReadOnly になっていないか」
「RS.Supports(adUpdate) が True を返すか」
この2点を確認してください。これらの条件を満たさない場合、読取専用として扱われます。
だっちゃんさん:
> 使用していますよね?提示されたプログラムを拝見するとDataGridコントロールの
> DataSourceに直接検索結果を設定しているだけに見えるのですが?
Recordsetオブジェクト(もしくは自作したデータソースクラス)を
DataSourceプロパティに指定するのは、さほど珍しい事ではありませんよ。
むしろ、ADODCやDataEnvironmentは、コントロール数分の接続が発生するため、
使用を控える人は多いようです。……特に、業務アプリでは。
こんちは。
私も以前JINさんと同じようなことをして今回書いた方法で
解消したのですが、「静的バッチカーソル」って方法もあるのですね。
ひとつ勉強になりました。
おはようございます。
返信が遅くなってすいません。お盆で実家に帰っていたもので・・・(汗
>だっちゃん様
返信ありがとうございます。
さっそくADOのヘルプも参照してみたいと思います。
>魔界の仮面弁士様
返信ありがとうございます。
さっそく試してみようと思います。
いつも仮面弁士様の説明には勉強させていただいて、お世話になっています。
今後もお力添えをよろしくお願いします。
おはようございます。たびたび申し訳ありませんが。
再確認し、再度いろいろ試したところ
やはりデータグリッドにはデータが反映されず、編集もできません。
そこで、一番初めにのせた例ではなく、実際のコードをのせますので。(実際の方が結構複雑なので・・・汗)
よろしくお願いします。
テーブルは、
テーブルA[M1_SYOHIN_TBL]
M1_SYOHIN_CD...商品コード
M1_SYOHIN_NM...商品名
M1_SYOHIN_TN...商品単価
テーブルB[M2_TENKAI_TBL]
M2_SYOHIN_CD...商品コード
M2_SIZAI_CD...商品コード(資材用)
M2_HITUYOU_SU...必要な数
があり、一つの商品を作るのに必要な商品をテーブルBに保存してあります。
フォームA
テキスト1[Shohin_No](商品コード)
テキスト2[Syohin_Nm](商品名)
テキスト3[Syohin_Tn](商品単価)
データグリッド1[Tenkai]
(商品コード(visible = false))
(商品コード(資材用)・商品名(資材用))
(商品単価(資材用)・必要数)
があり、フォームのテキスト1に商品コードを打ち込むと。
テキスト2とテキスト3にテーブルAからの値が入り
データグリッドにも商品コードと必要数はテーブルBから、
商品名と商品単価は商品コード(資材用)を元にテーブルAから値取得します。
コードは下記のとおりです。
Option Explicit
'追加
Dim CN As New ADODB.Connection
'オープン
Private Sub Form_Load()
Dim DB As String 'データベース名
DB = GetDataSorce()
CN.ConnectionString = "Provider=SQLOLEDB.1;" & "Data Source" & DB
CN.Open
Set Me.Tenkai.DataSource = Nothing
End Sub
'データソース名の取得
Private Function GetDataSorce() As String
Dim startPos As Long '開始位置
Dim endPos As Long '終了位置
Dim skip As Long '読み飛ばす文字数
'データソースの取得
startPos = InStr(1, DE1.Con1.ConnectionString, "Data Source=", vbTextCompare)
endPos = InStr(startPos, DE1.Con1.ConnectionString, ";", vbTextCompare)
skip = Len("Data Source=")
GetDataSorce = Mid(DE1.Con1.ConnectionString, startPos + skip, endPos - (startPos + skip))
End Function
'テキスト1のロストフォーカス処理
Private Sub Syohin_No_LostFocus()
Call RefreshData
End Sub
'SQL処理
Private Sub RefreshData()
Dim RS As New ADODB.Recordset
Dim RS2 As New ADODB.Recordset
Dim strSQL As String
'SQLステートメント
strSQL = "SELECT M1_SYOHIN_CD,M1_SYOHIN_NM,M1_TANI1_CD FROM M1_SYOHIN_TBL WHERE M1_SYOHIN_CD = '" & Me.Syohin_No & "'"
'レコードセット取得
RS.Open strSQL, CN, , adLockOptimistic
Set Me.Syohin_Nm.DataSource = RS
Set Me.Syohin_Tn.DataSource = RS
Me.Syohin_Nm.DataField = "M1_SYOHIN_NM"
Me.Syohin_Tn.DataField = "M1_TANI1_CD"
strSQL = "select M2_SYOHIN_CD,M2_SIZAI_CD,M2_HITUYO_SU,M1_SYOHIN_NM,M1_TANI1_CD FROM M2_TENKAI_TBL INNER JOIN M1_SYOHIN_TBL ON M2_SIZAI_CD = M1_SYOHIN_CD WHERE M2_SYOHIN_CD ='" & Me.Syohin_No & "'"
RS2.Open strSQL, CN, adOpenStatic, adLockOptimistic
Set Me.Tenkai.DataSource = RS2
Me.Tenkai.Columns("商品名").DataField = "M1_SYOHIN_NM"
End Sub
'レコードの追加時
Private Sub Tenkai_OnAddNew()
Me.Tenkai.Columns("製品コード").Value = Me.Syohin_No
End Sub
>Me.Syohin_Nm.Text = RS.Collect("M1_SYOHIN_NM") & ""
>のように、Textプロパティに、値を直接送り込むのが一般的かと思います。
商品コードを打ったときに、データがない場合はエラーが出るので
やはりこの形をとらせていただきました。
>データグリッドに割り当てるまでは良いですが、そのあと、
>せっかくのRecordsetを閉じてしまっているからだと思います。
レコードセットを閉じなくてもいいように2つ作りました。
>「RS.LockType が adLockReadOnly になっていないか」
>「RS.Supports(adUpdate) が True を返すか」
これも大丈夫だと思います。
よろしくお願いします。
ツイート | ![]() |