こんにちは。
recordsetの結果をDictionaryにいれたいと思っています。
環境はWindows Vista、vbScriptで書いています。
set dc = createobject("scripting.dictionary")
Set rs = Server.CreateObject("ADODB.Recordset")
rs.open (sql文), con
for i = 0 to rs.recordcount -1
for j = 0 to rs.fields.count - 1
dc.add rs.fields(j).name, rs.fields(j).value
next
next
ちょっとイメージっぽく書きましたが(このままではエラーでます)、要は複数のフィールドを持つ複数のレコードを入れられないかということです。
色々調べたりしてみたのですがわかりません。
できないのかな?と思いました。
もしできるなら書き方をご教授頂けたらと思います。
よろしくお願いします。
A 回答 (8件)
- 最新から表示
- 回答順に表示
No.8
- 回答日時:
>>dc(i) = rs.GetRows(1, adBookmarkCurrent)
>これが理想なのですが、dc(i)という書き方はエラーになってしまいます。
>オブジェクトにindexがつけられればいいのですが。
"C:\temp\test.xls"のSheet1に適当な65535件のデータでテストしたコードを載せておきます。
特にエラーは出ないので、データもしくは環境のせいでしょうか。
>dc(i) = rs.GetRows(1, adBookmarkCurrent)
とは、
dc.Add i, rs.GetRows(1, adBookmarkCurrent)
と一緒で、i を index としています。
Const adBookmarkCurrent = 0
Const adOpenStatic = 3
Const wkName = "C:\temp\test.xls"
Dim con
Dim rs
Dim sql
Dim dc
Dim i
'On Error Resume Next
Set con = CreateObject("ADODB.Connection")
With con
.Provider = "Microsoft.Jet.OLEDB.4.0"
.Properties("Extended Properties") = "Excel 8.0"
.Properties("Data Source") = wkName
.Open
End With
sql = "SELECT * FROM [Sheet1$]"
Set rs = CreateObject("ADODB.Recordset")
Set dc = CreateObject("scripting.dictionary")
rs.Open sql, con, adOpenStatic
Stop
For i = 1 To rs.RecordCount
dc(i) = rs.GetRows(1, adBookmarkCurrent)
Next
rs.Close
con.Close
Stop
MsgBox dc(1)(0, 0) & vbTab & dc(1)(1, 0) & vbTab & dc(1)(2, 0)
MsgBox dc(2)(0, 0) & vbTab & dc(2)(1, 0) & vbTab & dc(2)(2, 0)
MsgBox dc(dc.Count)(0, 0) & vbTab & dc(dc.Count)(1, 0) & vbTab & dc(dc.Count)(2, 0)
Set dc = Nothing
Set rs = Nothing
Set con = Nothing
If Err.Number <> 0 Then
MsgBox Err.Number & vbLf & Err.Description
Else
MsgBox "end"
End If
#修正なしでVBAでも試せます。
No.7
- 回答日時:
いろいろ回答はあるけれど、結局どのようなデータを持ってどのように取り出すかがわからないとうろうろするばかりではないでしょうか。
私はキーを連結して1つのキーにしてしまえばと書いたけど
取り出すときに取り出すキーが二つともわかっていればこれでいいでしょう。
でも最初のキーで取り出したデータの中に2番目のキーがあるような場合はお手上げです。
正直連想配列の必要も無い場合もあるのではないかとも思っています。
どのようなデータを「どのように取り出したいか提示してもらえると回答も正解に塚づくのではないでしょうか、
No.6
- 回答日時:
Recordsetの結果をDictionaryに入れる時、何か別のkeyでレコード単位で入れるのですか?
それともfields.Nameをkeyにしてフィールド単位で入れるのですか?
GetRowsを使ってレコード単位で入れるなら
Const adBookmarkCurrent = 0
Const adOpenStatic = 3
':
rs.Open sql, con, adOpenStatic
Stop
For i = 1 To rs.RecordCount
dc(i) = rs.GetRows(1, adBookmarkCurrent)
Next
rs.Close
con.Close
Stop
MsgBox dc(1)(0, 0) & vbTab & dc(1)(1, 0) & vbTab & dc(1)(2, 0)
MsgBox dc(2)(0, 0) & vbTab & dc(2)(1, 0) & vbTab & dc(2)(2, 0)
こんな感じになるかと。
フィールド単位で、LoopでField別に配列を作ってもそんなに時間かかりますか?
Dim v, w, x
':
rs.Open sql, con
Stop
v = rs.GetRows
ReDim w(UBound(v, 2))
For i = 0 To UBound(v, 1)
For j = 0 To UBound(v, 2)
w(j) = v(i, j)
Next
dc(rs.fields(i).Name) = w
Next
rs.Close
con.Close
Stop
x = dc.keys
MsgBox x(0) & vbTab & dc(x(0))(0) & vbTab & dc(x(0))(1) & vbTab & dc(x(0))(2)
MsgBox x(1) & vbTab & dc(x(1))(0) & vbTab & dc(x(1))(1) & vbTab & dc(x(1))(2)
Dictionaryに格納した後どうやって利用するかなのだと思いますが、
v = rs.GetRows
ただ単に配列で保持しておくっていう意味じゃないんですよね?
この回答への補足
お返事ありがとうございます。
>dc(i) = rs.GetRows(1, adBookmarkCurrent)
これが理想なのですが、dc(i)という書き方はエラーになってしまいます。
オブジェクトにindexがつけられればいいのですが。
>フィールド単位で、LoopでField別に配列を作ってもそんなに時間かかりますか?
処理件数によっては遅くなるのでは?という古い考えがありました;
経験言語の違う数名で話していたのですが、たとえばPHP経験者は連想配列で渡してもらいたい、他の者はオブジェクトで渡すべきだ(recordsetかDictionary)、などと色々意見がでまして。
私はVB経験者としてrecordsetかgetrowsでの配列渡しを提案したのですが、Rubyなどのように1行でできないか?と言われまして試行錯誤していました。
(つまり共通ライブラリの関数にsqlを渡すと接続・実行・切断を行って結果をもらいたい、と)
recordsetはcloneが作れますが、さすがにコネクト切断すると中身も失われてしまいます。
格納後の処理の利便性ではなく、そういった経緯で悩んでいました。
No.5
- 回答日時:
#2&3です。
VBSでcollectionは使えないのですね、失礼しました。それでは、下記の様なのは如何でしょうか。安定して動くかどうかは定かでありません。珍奇な思いつきかも...
Sub test3()
Dim dic As Object, tempDic As Object
Dim i As Long
Set dic = CreateObject("Scripting.Dictionary")
For i = 1 To 2
Set tempDic = CreateObject("Scripting.Dictionary")
tempDic.Add "field_a", i
tempDic.Add "field_b", "code" & Format(i, "00")
dic.Add CStr(i), tempDic
Set tempDic = Nothing
Next i
For i = 1 To 2
Debug.Print dic.Item(CStr(i)).Item("field_a")
Debug.Print dic.Item(CStr(i)).Item("field_b")
Next i
End Sub
#2が二次元配列で可能かどうかはお試し下さい。
No.3
- 回答日時:
#2です。
ちょっとピント外れでしたか。下記の様なのは如何でしょうか。"a","b"のところをフィールド名にします。これなら、異なる型のフィールドのデータが入れられます。
Sub test2()
Dim dic As Object
Dim myKey As String
Dim tempCollection As Collection
Set dic = CreateObject("Scripting.Dictionary")
Set tempCollection = New Collection
myKey = "1"
tempCollection.Add Item:=123, key:="a"
tempCollection.Add Item:="ABC", key:="b"
dic.Add myKey, tempCollection
'dictionaryにセット後、消してしまっても、dictionaryの中味は保持されている
Set tempCollection = Nothing
Debug.Print dic.Item(myKey)("a")
Debug.Print dic.Item(myKey)("b")
End Sub
お返事ありがとうございます。
Collectionを調べてみたのですが、VBScriptではCollectionが使えないようです;;
参考になりました。ありがとうございます!
No.2
- 回答日時:
dictionaryに配列を入れるコードをみたことがあります。
試しにやってみたら、下記の通りできました。VBAですが、ご参考まで。
Sub test()
Dim dic As Object
Dim myKey As String
Dim i As Long
Set dic = CreateObject("Scripting.Dictionary")
myKey = "1"
dic.Add myKey, Array(1, 2, 3, 4, 5)
For i = 0 To UBound(dic.Item(myKey))
Debug.Print dic.Item(myKey)(i)
Next i
End Sub
この回答への補足
お返事ありがとうございます。
dic.Add myKey, Array(1, 2, 3, 4, 5)
のArrayは1次元配列じゃないとやっぱりだめでしょうか?
Getrowsを指定できれば使えるな~と思いました。
もし1次元配列で指定しなければいけないのなら、ループでField別に配列を作らないといけないので、処理時間をくってしまいそうなので、おとなしくrecordsetにしようと思います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) access count数を変数に格納 2 2022/03/30 19:21
- Visual Basic(VBA) データベースから絞り込んでデータを読み込み 1 2023/02/21 19:51
- Access(アクセス) DoCmd.SearchForRecord が動かない時の解決方法 3 2022/07/22 15:31
- Visual Basic(VBA) excel vbaでvlooupの変数がわかりません。 7 2022/05/30 09:35
- Access(アクセス) チェックボックスにチェックが入った後の挙動 1 2022/08/21 12:39
- Access(アクセス) docmd.gotorecordを起動するには 5 2022/06/17 15:20
- Excel(エクセル) VBA フォルダ見える化のコードについて 2 2023/06/19 15:04
- Access(アクセス) 実行時エラー3131 FROM 句の構文エラーです について 7 2022/06/13 15:45
- Excel(エクセル) VBAで組み合わせ算出やCOUNTIFSの処理を高速化したいです。 4 2022/04/07 02:38
- Visual Basic(VBA) 前回ご教授いただいたコードに覚えたてのループ処理で品名りんごAから順に20回for nextでループ 7 2023/01/13 22:01
このQ&Aを見た人はこんなQ&Aも見ています
-
風水の観点で選ぶ観葉植物とは?置き場所や上げたい運気ごとの注意点を紹介!
観葉植物で運気をアップするコツを、風水デザイン1級建築士の福島昌彦さんに伺った。
-
Accessのテーブルデータを一気にVBAで追加したい・・
その他(データベース)
-
レコードセットの中身を配列に、そしてワークシートに。
Visual Basic(VBA)
-
VBAでループ内で使う変数名を可変にできないか。
Visual Basic(VBA)
-
-
4
EXCELで特定のセルに表示された項目をヘッダーやフッターに出力するには
Excel(エクセル)
-
5
選択したチェックボックスのみチェックを入れたいのですが
その他(データベース)
-
6
Dictionaryについてその2
Microsoft ASP
-
7
実行したSQLの結果を返す方法
Visual Basic(VBA)
-
8
ADOを使ったDBアクセス後のメモリ解放
その他(データベース)
-
9
ADOのCursorLocationプロパティ
Visual Basic(VBA)
-
10
Accessのフォームのみ表示させたい
Access(アクセス)
-
11
レコードセットにnullの場合
Visual Basic(VBA)
-
12
VBで引数にDictionaryオブジェクトを使用する方法
Visual Basic(VBA)
-
13
エクセルで複数列の検索をマクロで行いたい
Excel(エクセル)
-
14
Accessを開くと「排他モードじゃないので変更しても保存できない」との旨の表示が出てしまう。
Access(アクセス)
-
15
access vbaにてテンポラリーテーブルが作りたいです。
Access(アクセス)
-
16
PDFファイルを開かずに印刷したい
Visual Basic(VBA)
-
17
Access サブフォームでの選択行の取得
その他(データベース)
-
18
Accessの「IIF」に相当するSQL関数(ADOでOracleに接続時)
その他(データベース)
-
19
VB6+SQL サーバー 2000 で 実行時エラー '3704' がでます:
Visual Basic(VBA)
-
20
[VBA] ADOの Clone と AddNew
その他(プログラミング・Web制作)
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
クリスタルレポートで困ってい...
-
日付と文字列を条件としてDLook...
-
2つ目のレコードの値を取得す...
-
accessでフィールド追加のあと...
-
Accessの画像挿入のVBAコード
-
オートナンバー型を抽出条件に...
-
クリスタルレポート(8.5)の書式...
-
SQLで複数のテーブルと結合した...
-
Accessのフィールド名に半角括...
-
(ADO)フィールド名から取得し...
-
DataTableに特定のフィールドが...
-
エクセルVBAでSQLを使ってアク...
-
C#で変数名の取得
-
フィールド名をループの添え字...
-
SQLでの日付比較
-
INT64対応のprintf系関数はあり...
-
VBA 変数名に変数を使用したい。
-
【ExcelVBA】値を変更しながら...
-
C#でbyte配列から画像を表示さ...
-
【C#】textBoxの指定行のデータ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Accessのフィールド名に半角括...
-
DataTableに特定のフィールドが...
-
accessでフィールド追加のあと...
-
INT64対応のprintf系関数はあり...
-
2つ目のレコードの値を取得す...
-
Access 2010で実行時エラー3061
-
日付と文字列を条件としてDLook...
-
AccessのDAOでフィールド名を配...
-
SQLで複数のテーブルと結合した...
-
テーブルのデータ型の変更がで...
-
フィールド名をループの添え字...
-
クリスタルレポート(8.5)の書式...
-
AccessVBAで他テーブルのデータ...
-
Accessの画像挿入のVBAコード
-
アクセスでADO 並べ替えが適用...
-
NULLを含む文字列の結合で...
-
クリスタルレポートで文字列の...
-
ACCESSデータベースにV...
-
ノーツ:ユーザ名から別名を取...
-
Access クエリで変数を参照する...
おすすめ情報