
こんにちは。
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も見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
accessでフィールド追加のあと...
-
INT64対応のprintf系関数はあり...
-
Accessのフィールド名に半角括...
-
DataTableに特定のフィールドが...
-
NULLを含む文字列の結合で...
-
Access 2010で実行時エラー3061
-
日付と文字列を条件としてDLook...
-
DataTableのselectメソッド
-
2つ目のレコードの値を取得す...
-
ADOをし使用して、Accessのテー...
-
週の日数は7日ですが、これを表...
-
CurrentRecord について
-
C#で変数名の取得
-
クリスタルレポートのテキスト...
-
ACCESSで視覚的タイムテーブル...
-
テーブルのデータ型の変更がで...
-
アクセスでADO 並べ替えが適用...
-
AS/400の論理ファイルで年度だ...
-
PDF-acrobat数値ありフィールド...
-
クリスタルレポート(8.5)の書式...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
INT64対応のprintf系関数はあり...
-
accessでフィールド追加のあと...
-
2つ目のレコードの値を取得す...
-
Accessのフィールド名に半角括...
-
DataTableに特定のフィールドが...
-
テーブルのデータ型の変更がで...
-
ACCESSデータベースにV...
-
クリスタルレポート(8.5)の書式...
-
クリスタルレポートで文字列の...
-
日付と文字列を条件としてDLook...
-
Access 2010で実行時エラー3061
-
ADOでNullフィールドの抽出
-
Access クエリで変数を参照する...
-
NULLを含む文字列の結合で...
-
AccessのDAOでフィールド名を配...
-
アクセス ADO Null以外のレコ...
-
クリスタルレポートで0件時の表示
-
FTPサーバーから受信したファイ...
-
C#で変数名の取得
-
c言語で自分のホームディレク...
おすすめ情報