こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

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

わかる方ご教授願います

投稿日時 - 2008-05-09 11:59:20

QNo.4008848

すぐに回答ほしいです

質問者が選んだベストアンサー

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で名前が定義されていないか)も確認してください。

投稿日時 - 2008-05-12 12:27:35

補足

できましたありがとうございます
mdbの数が多すぎが原因だったようです
ありがとうございます
感謝感激です

投稿日時 - 2008-05-12 15:17:40

このQ&Aは役に立ちましたか?

2人が「このQ&Aが役に立った」と投票しています

回答(11)

ANo.10

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

投稿日時 - 2008-05-10 06:45:02

補足

お返事ありがとうございます
下記削除実行しました
Worksheets("ABC").Range...<-この行削除
下記でエラーします
MsgBox "終了アドレス=

よろしくおねがいます

投稿日時 - 2008-05-12 11:22:55

ANo.9

すごい既回答ですが、ADOなら各レコードの各フィールドが捉えられるはずです。これを1レコードの各フィールドを行ポインタ変数 i を持って+1して行方向(下方向)に流して代入し、レコードは列ポインタ j 持って、レコードが進むと、+1して列方向(右方向)に流して「フィールドごとに」セル(i,j)に代入すればよいと思うが。
(この方法はコピー法ではない)

投稿日時 - 2008-05-09 23:09:22

その他のコードは、書き換える必要はありません
これは、私が示したコードのことです。

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

投稿日時 - 2008-05-09 17:32:17

補足

お返事ありがとうございます
現在上記標準モジュール作成(.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
上記実行すると
コンパイルエラー
メソッドまたはデータメンバが見つかりません。
とでます。
どこがいけないのでしょうか?
よろしくお願い申し上げます

投稿日時 - 2008-05-12 11:51:33

お礼

できましたありがとうございます
mdbの数が多すぎが原因だったようです
ありがとうございます
感謝感激です

投稿日時 - 2008-05-12 15:19:19

エラーになる行をコメントアウトにして、それ以下でデータを表示してみます。
下記のようになるようにしてみてください。
どこでエラーになりますか?

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.
差し支えなければ、"開始セル名"を教えてください。

投稿日時 - 2008-05-09 16:53:05

補足

お返事ありがとうございます

開始セル名は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
ここででます
よろしくお願いします

投稿日時 - 2008-05-09 17:16:40

Q、下記のどの部分に記述すればよいのですか?
A、先のコードのSQL文を書き換えて開始行と開始列を指定するだけです。

その他のコードは、書き換える必要はありません。

X  N = UBound(strEmployees())
O  N = UBound(strEmployees())-1

と、チト、修正は必要ですが・・・。
つまり、Access からのデータ取得手続きは一切関数任せということです。

投稿日時 - 2008-05-09 15:52:41

補足

ええ?
再確認ですが
下記修正しましたがつじつまがあわなくて
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
上記はどの部分で記述すればよいですか?

投稿日時 - 2008-05-09 16:00:54

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
に変更

投稿日時 - 2008-05-09 15:24:22

補足

お返事ありがとうございます
だめです
実行時エラー1004
アプリケーション定義またはオブジェクトの定義エラーです
になります

又、デバックは
Worksheets("シート名").Range(Worksheets("シート名").Range("開始セル名"), Worksheets("シート名").Range("開始セル名").Offset(myRs.Fields.Count - 1, myRs.RecordCount - 1)) = myRs.GetRows
に色がつきます

投稿日時 - 2008-05-09 15:35:04

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
に変更

投稿日時 - 2008-05-09 15:17:19

こんなのはどうでしょうか?

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
に変更

投稿日時 - 2008-05-09 15:09:12

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関数を補足します。

投稿日時 - 2008-05-09 13:11:15

補足

本当にうごきますか?
下記のどの部分に記述すればよいのですか?

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

投稿日時 - 2008-05-09 14:28:09

ANo.1

データベースではレコードは上から下に展開するものというのが決まり事です
Access側や取り込むときに何とかすることは出来ません
取り込んでからExcelの行列変換機能で並べ替えるぐらいですね
ただし、Excelでも「データ」関連の機能を使うにはレコードが上下に並んでいる[リスト]になっていることが必要条件ですよ

投稿日時 - 2008-05-09 12:41:11

あなたにオススメの質問