- ベストアンサー
EXCEL→Access ADO接続
お世話になります 現在ADOにてEXCEL側からAccessDBにアクセスし 値を取得しているのですが 現在下方向に貼り付けしているのですが 横方向に貼り付けさせる方法はありますか? 下記参考(現状VBAです) 現状:日付で絞込みをしています 日付け絞込みをしてヒットしたものに対して下方向に貼り付けています それを横方向に貼り付けさせたいのです Private Sub CommandButton1_Click() Dim myConn As ADODB.Connection Dim myRs As ADODB.Recordset Dim mySQL As String Dim myConstr As String Dim myDBFName As String Dim myPswd As String Dim tableName As String Dim orderDate As String Dim shipDate As String orderDate = Format(DateValue(DTPicker1.Value), "mm/dd/yyyy") shipDate = Format(DateValue(DTPicker2.Value), "mm/dd/yyyy") myDBFName = "Accessパス" myPswd = "" myConstr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" _ & myDBFName & ";Jet OLEDB:Database Password=" & myPswd & ";" mySQL =SQL文 Set myConn = New ADODB.Connection myConn.Open myConstr Set myRs = New ADODB.Recordset myRs.Open mySQL, myConn Worksheets("シート名").Range("開始セル名").CopyFromRecordset myRs myRs.Close Set myRs = Nothing myConn.Close Set myConn = Nothing Unload Me End Sub わかる方ご教授願います
- みんなの回答 (11)
- 専門家の回答
質問者が選んだベストアンサー
ANo.10です。 >下記でエラーします >MsgBox "終了アドレス= エラーの行は残したまま、エラーになる前の所に、 MsgBox "Fields.Count=" & myRs.Fields.Count MsgBox "RecordCount=" & myRs.RecordCount を入れてください。 どんな表示になりますか? または、エラーが起こる場合は、どんなエラーですか? または、ここではエラーが起こらず、MsgBox "終了アドレス="の所でエラーになる場合は、どんなエラーですか? またはエラーの起こる、 MsgBox "終了アドレス=" & Worksheets("ABC").Range("F17").Offset(myRs.Fields.Count - 1, myRs.RecordCount - 1).Address の行の"ABC"と"F17"が全角になっていないか確認してください。 また、名前の定義がされていないか(Excel側で[挿入][名前]でABCやF17で名前が定義されていないか)も確認してください。
その他の回答 (10)
- fumufumu_2006
- ベストアンサー率66% (163/245)
ANo.7です。 ANo.7の回答で、エラーの部分の命令は2度現れます。 1度目はコメントアウトにしてほしいと書いたのですが、削除して実行してください。 これは、この命令のどの部分がエラーを起こしているのか表示するために、その1文をコメントにして、各処理を分割して実行表示しているプログラムです。 そして、最後に同じ命令を行っています。(これがあればいいので) 説明の仕方が悪くてすみません。 myRs.Open mySQL, myConn, adOpenKeyset Worksheets("ABC").Range...<-この行削除 Dim d() As Variant .... Worksheets("ABC").Range(Worksheets("ABC").Range("F17"), Worksheets("ABC").Range("F17").Offset(myRs.Fields.Count - 1, myRs.RecordCount - 1)) = myRs.GetRows
補足
お返事ありがとうございます 下記削除実行しました Worksheets("ABC").Range...<-この行削除 下記でエラーします MsgBox "終了アドレス= よろしくおねがいます
- imogasi
- ベストアンサー率27% (4737/17069)
すごい既回答ですが、ADOなら各レコードの各フィールドが捉えられるはずです。これを1レコードの各フィールドを行ポインタ変数 i を持って+1して行方向(下方向)に流して代入し、レコードは列ポインタ j 持って、レコードが進むと、+1して列方向(右方向)に流して「フィールドごとに」セル(i,j)に代入すればよいと思うが。 (この方法はコピー法ではない)
その他のコードは、書き換える必要はありません これは、私が示したコードのことです。 Const 開始行 = 1 Const 開始列 = 1 Private Sub CommandButton1_Click() Dim I As Integer Dim N As Integer Dim strEmployees() As String strEmployees() = Split(DBSelect("質問者のSQL文"), ";") N = UBound(strEmployees()) - 1 For I = 0 To N Me.Cells(開始行, 開始列 + I) = strEmployees(I) Next I End Sub これで、開始行の開始列から横にデータを表示します。 コピぺ方式だと縦に自動表示されます。 そういうエクセルの表示機能を使わずにVBAで横に表示する訳です。 strEmployees() = Split(DBSelect("質問者のSQL文"), ";") N = UBound(strEmployees()) - 1 For I = 0 To N Me.Cells(開始行, 開始列 + I) = strEmployees(I) Next I 実質、僅か5行ですから、やっていることは理解できませんか? <アドバイス> このように僅か数行で目的を達成するには、作業を分割することです。 Accessからのデータの取得手続きは繰り返し発生するので、そこは関数に任せるのが一番。 CommandButton1_Click()では、関数から受け取ったデータを並べるだけに。 そうすると、何も考えないで2、3分でコードは書けます。 [イミディエイト] ? DBSelect("SELECT * FROM 担当者") 1;01: AAAA;True;True;2;02: BBBB;True;True;3;03: CCCC;False;True; ? DBSelect("SELECT * FROM 担当者",,vbcrlf) 1;01: AAAA;True;True; 2;02: BBBB;True;True; 3;03: CCCC;False;True; では、一体、SQL文の実行結果をどのように受け取れば簡単に配列に取り込めるのかです。 それは、上述のように列と行とのデータを区切り子で区切った文字列として受け取ればいいです。 strEmployees() = Split(DBSelect("質問者のSQL文"), ";") そうすりゃ、この1行で配列に取り込めます。 試しに、上の"質問者のSQL文"部分を正しく書いてコマンドボタンをクリックすりゃ表示されますよ。 <準備> 以下の関数を標準モジュールにコピペ。 もちろん、記号定数 pubCNNSTRING は、ちゃんと設定して下さい。 Public Const pubCNNSTRING = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\xxxx\xxxx.mdb" Public Function DBSelect(ByVal strQuerySQL As String, _ Optional cel_separator As String = ";", _ Optional row_separator As String = "") As String On Error GoTo Err_DBSelect Dim I As Integer Dim J As Integer Dim R As Integer Dim C As Integer Dim M As Integer Dim N As Integer Dim rst As ADODB.Recordset Dim fld As ADODB.Field Dim strList As String Set rst = New ADODB.Recordset With rst .Open strQuerySQL, _ pubCNNSTRING, _ adOpenStatic, _ adLockReadOnly If Not .BOF Then M = .RecordCount - 1 N = .Fields.Count - 1 .MoveFirst For R = 0 To M C = -1 For Each fld In .Fields C = C + 1 strList = strList & fld.Value & "" & cel_separator Next fld strList = strList & row_separator .MoveNext Next R Else strList = "" End If End With Exit_DBSelect: On Error Resume Next rst.Close Set rst = Nothing DBSelect = strList Exit Function Err_DBSelect: MsgBox "SELECT 文の実行時にエラーが発生しました。(DBSelect)" & Chr$(13) & Chr$(13) & _ "・Err.Description=" & Err.Description & Chr$(13) & _ "・SQL Text=" & strQuerySQL, _ vbExclamation, " 関数エラーメッセージ" Resume Exit_DBSelect End Function
お礼
できましたありがとうございます mdbの数が多すぎが原因だったようです ありがとうございます 感謝感激です
補足
お返事ありがとうございます 現在上記標準モジュール作成(.mdb)のパス記載し フォーム内 下記を記述し(SQL文作成)しました Const 開始行 = 1 Const 開始列 = 1 Private Sub CommandButton1_Click() Dim I As Integer Dim N As Integer Dim strEmployees() As String strEmployees() = Split(DBSelect("質問者のSQL文"), ";") N = UBound(strEmployees()) - 1 For I = 0 To N Me.Cells(開始行, 開始列 + I) = strEmployees(I) Next I End Sub 上記実行すると コンパイルエラー メソッドまたはデータメンバが見つかりません。 とでます。 どこがいけないのでしょうか? よろしくお願い申し上げます
- fumufumu_2006
- ベストアンサー率66% (163/245)
エラーになる行をコメントアウトにして、それ以下でデータを表示してみます。 下記のようになるようにしてみてください。 どこでエラーになりますか? ANo.5で変更して下記の部分 Worksheets("シート名").Range(Worksheets("シート名").Range("開始セル名"), Worksheets("シート名").Range("開始セル名").Offset(myRs.Fields.Count - 1, myRs.RecordCount - 1)) = myRs.GetRows をコメントアウトして、それ以下を追加してみてください 'Worksheets("シート名").Range(Worksheets("シート名").Range("開始セル名"), Worksheets("シート名").Range("開始セル名").Offset(myRs.Fields.Count - 1, myRs.RecordCount - 1)) = myRs.GetRows Dim d() As Variant d = myRs.GetRows MsgBox "フィールド数=" & UBound(d, 1) + 1 MsgBox "レコード数=" & UBound(d, 2) + 1 MsgBox "A1に入るデータ=" & d(0, 0) MsgBox "開始アドレス=" & Worksheets("シート名").Range("開始セル名").Address MsgBox "終了アドレス=" & Worksheets("シート名").Range("開始セル名").Offset(myRs.Fields.Count - 1, myRs.RecordCount - 1).Address MsgBox "コピー先範囲をselectしました" Worksheets("シート名").Select Worksheets("シート名").Range(Worksheets("シート名").Range("開始セル名"), Worksheets("シート名").Range("開始セル名").Offset(myRs.Fields.Count - 1, myRs.RecordCount - 1)).Select myRs.MoveFirst Worksheets("シート名").Range(Worksheets("シート名").Range("開始セル名"), Worksheets("シート名").Range("開始セル名").Offset(myRs.Fields.Count - 1, myRs.RecordCount - 1)) = myRs.GetRows p.s. 差し支えなければ、"開始セル名"を教えてください。
補足
お返事ありがとうございます 開始セル名はF17にしております Private Sub CommandButton1_Click() Dim myConn As ADODB.Connection Dim myRs As ADODB.Recordset Dim mySQL As String Dim myConstr As String Dim myDBFName As String Dim myPswd As String Dim tableName As String Dim orderDate As String Dim shipDate As String orderDate = Format(DateValue(DTPicker1.Value), "mm/dd/yyyy") shipDate = Format(DateValue(DTPicker2.Value), "mm/dd/yyyy") myDBFName = "アクセスパス" myPswd = "" myConstr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" _ & myDBFName & ";Jet OLEDB:Database Password=" & myPswd & ";" mySQL = "SELECT B.日付 FROM B " & _ "WHERE(((B.日付)>=#" & orderDate & "#) AND ((B.日付)<=#" & shipDate & _ "#));" Set myConn = New ADODB.Connection myConn.Open myConstr Set myRs = New ADODB.Recordset myRs.Open mySQL, myConn, adOpenKeyset Worksheets("ABC").Range(Worksheets("ABC").Range("F17"), Worksheets("ABC").Range("F17").Offset(myRs.Fields.Count - 1, myRs.RecordCount - 1)) = myRs.GetRows Dim d() As Variant d = myRs.GetRows MsgBox "フィールド数=" & UBound(d, 1) + 1 MsgBox "レコード数=" & UBound(d, 2) + 1 MsgBox "A1に入るデータ=" & d(0, 0) MsgBox "開始アドレス=" & Worksheets("ABC").Range("F17").Address MsgBox "終了アドレス=" & Worksheets("ABC").Range("F17").Offset(myRs.Fields.Count - 1, myRs.RecordCount - 1).Address MsgBox "コピー先範囲をselectしました" Worksheets("ABC").Select Worksheets("ABC").Range(Worksheets("ABC").Range("F17"), Worksheets("ABC").Range("F17").Offset(myRs.Fields.Count - 1, myRs.RecordCount - 1)).Select myRs.MoveFirst Worksheets("ABC").Range(Worksheets("ABC").Range("F17"), Worksheets("ABC").Range("F17").Offset(myRs.Fields.Count - 1, myRs.RecordCount - 1)) = myRs.GetRows myRs.Close Set myRs = Nothing myConn.Close Set myConn = Nothing Unload Me End Sub エラーは Worksheets("ABC").Range(Worksheets("ABC").Range("F17"), Worksheets("ABC").Range("F17").Offset(myRs.Fields.Count - 1, myRs.RecordCount - 1)) = myRs.GetRows ここででます よろしくお願いします
Q、下記のどの部分に記述すればよいのですか? A、先のコードのSQL文を書き換えて開始行と開始列を指定するだけです。 その他のコードは、書き換える必要はありません。 X N = UBound(strEmployees()) O N = UBound(strEmployees())-1 と、チト、修正は必要ですが・・・。 つまり、Access からのデータ取得手続きは一切関数任せということです。
補足
ええ? 再確認ですが 下記修正しましたがつじつまがあわなくて Private Sub CommandButton1_Click() Dim myConn As ADODB.Connection Dim myRs As ADODB.Recordset Dim mySQL As String Dim myConstr As String Dim myDBFName As String Dim myPswd As String Dim tableName As String Dim orderDate As String Dim shipDate As String orderDate = Format(DateValue(DTPicker1.Value), "mm/dd/yyyy") shipDate = Format(DateValue(DTPicker2.Value), "mm/dd/yyyy") myDBFName = "アクセスパス" myPswd = "" myConstr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" _ & myDBFName & ";Jet OLEDB:Database Password=" & myPswd & ";" mySQL = "SELECT B.担当者 FROM B " & _ "WHERE(((B.日付)>=#" & orderDate & "#) AND ((B.日付)<=#" & shipDate & _ "#));" Set myConn = New ADODB.Connection myConn.Open myConstr Set myRs = New ADODB.Recordset myRs.Open mySQL, myConn, adOpenKeyset Worksheets("シート名").Range(Worksheets("シート名").Range("開始セル"), Worksheets("シート名").Range("開始セル").Offset(myRs.Fields.Count - 1, myRs.RecordCount - 1)) = myRs.GetRows myRs.Close Set myRs = Nothing myConn.Close Set myConn = Nothing Unload Me End Sub これで修正したら先ほどのエラーになります N = UBound(strEmployees())-1 上記はどの部分で記述すればよいですか?
- fumufumu_2006
- ベストアンサー率66% (163/245)
ANo.3とANo.4です。 たびたびすみません、下のようではどうでしょうか? myRs.Open mySQL, myConn を myRs.Open mySQL, myConn, adOpenKeyset に変更(myRs.RecordCountが-1にならないようにするため) Worksheets("シート名").Range("開始セル名").CopyFromRecordset myRs を Worksheets("シート名").Range(Worksheets("シート名").Range("開始セル名"), Worksheets("シート名").Range("開始セル名").Offset(myRs.Fields.Count - 1, myRs.RecordCount - 1)) = myRs.GetRows に変更
補足
お返事ありがとうございます だめです 実行時エラー1004 アプリケーション定義またはオブジェクトの定義エラーです になります 又、デバックは Worksheets("シート名").Range(Worksheets("シート名").Range("開始セル名"), Worksheets("シート名").Range("開始セル名").Offset(myRs.Fields.Count - 1, myRs.RecordCount - 1)) = myRs.GetRows に色がつきます
- fumufumu_2006
- ベストアンサー率66% (163/245)
ANo.3です。 間違えました、下のようではどうでしょうか? Set myRs = New ADODB.Recordset を myRs.Open mySQL, myConn, adOpenKeyset に変更(myRs.RecordCountが-1にならないようにするため) Worksheets("シート名").Range("開始セル名").CopyFromRecordset myRs を Worksheets("シート名").Range(Worksheets("シート名").Range("開始セル名"), Worksheets("シート名").Range("開始セル名").Offset(myRs.Fields.Count - 1, myRs.RecordCount - 1)) = myRs.GetRows に変更
- fumufumu_2006
- ベストアンサー率66% (163/245)
こんなのはどうでしょうか? Set myRs = New ADODB.Recordset を myRs.Open mySQL, myConn, adOpenKeyset に変更(myRs.RecordCountが-1にならないようにするため) Worksheets("シート名").Range("開始セル名").CopyFromRecordset myRs を Worksheets("Sheet1").Range(Worksheets("Sheet1").Cells(1, 1), Worksheets("Sheet1").Cells(myRs.Fields.Count, myRs.RecordCount)) = myRs.GetRows に変更
Const 開始行 = 1 Const 開始列 = 1 Private Sub CommandButton1_Click() Dim I As Integer Dim N As Integer Dim strEmployees() As String strEmployees() = Split(DBSelect("SELECT 担当者名 FROM 担当者"), ";") N = UBound(strEmployees()) For I = 0 To N Me.Cells(開始行, 開始列 + I) = strEmployees(I) Next I End Sub <実行結果> 01: ○○ ○○__02: ○○ ○○__03: ○○ ○○ エクセルは操作したこともない門外漢ですが・・・。 一応、これでA1、A2、A3に取得したデータが表示されます。 For-Next文を使う初手の手法です。 この手法を使うには、一応、DBSelect関数の自作が必要です。 このような手法で構わなければ DBSelect関数を補足します。
補足
本当にうごきますか? 下記のどの部分に記述すればよいのですか? Private Sub CommandButton1_Click() Dim myConn As ADODB.Connection Dim myRs As ADODB.Recordset Dim mySQL As String Dim myConstr As String Dim myDBFName As String Dim myPswd As String Dim tableName As String Dim orderDate As String Dim shipDate As String orderDate = Format(DateValue(DTPicker1.Value), "mm/dd/yyyy") shipDate = Format(DateValue(DTPicker2.Value), "mm/dd/yyyy") myDBFName = "Accessパス" myPswd = "" myConstr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" _ & myDBFName & ";Jet OLEDB:Database Password=" & myPswd & ";" mySQL =SQL文 Set myConn = New ADODB.Connection myConn.Open myConstr Set myRs = New ADODB.Recordset myRs.Open mySQL, myConn Worksheets("シート名").Range("開始セル名").CopyFromRecordset myRs myRs.Close Set myRs = Nothing myConn.Close Set myConn = Nothing Unload Me End Sub
- CHRONOS_0
- ベストアンサー率54% (457/838)
データベースではレコードは上から下に展開するものというのが決まり事です Access側や取り込むときに何とかすることは出来ません 取り込んでからExcelの行列変換機能で並べ替えるぐらいですね ただし、Excelでも「データ」関連の機能を使うにはレコードが上下に並んでいる[リスト]になっていることが必要条件ですよ
補足
できましたありがとうございます mdbの数が多すぎが原因だったようです ありがとうございます 感謝感激です