[[20160816140239]] 『『マルチレコードについて』2』(フェンダー) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『『マルチレコードについて』2』(フェンダー)

以前この掲示板で
[[20140920112501]]
『マルチレコードについて』で
下記のデータを
アクセスに取り込んで
管理することで
お世話になり解決したのですが
再度ご説明いたします。

データ編集前

10,事務所1,1,2
20,Aさん,4,5,6
20,Bさん,7,8,9
20,Cさん,10,11,12
10,事務所2,13,14
20,Dさん,16,17,18
20,Eさん,19,20,21
20,Fさん,22,23,24
20,Gさん,25,26,27

のようなテストデータを

Sub main()

    Dim rs As DAO.Recordset
    Dim FSO As New FileSystemObject
    Dim mainStream As TextStream
    Dim 事務所 As String
    Dim strLine As String
    Set rs = CurrentDb.OpenRecordset("テーブル", dbOpenDynaset) 'テーブルファイルをセット
    Set mainStream = FSO.OpenTextFile("C:\temp\testout.txt", ForReading)
    Do Until mainStream.AtEndOfStream
        strLine = mainStream.ReadLine
        Select Case Split(strLine, ",")(0)
            Case "10"
                事務所 = strLine
            Case Else
                rs.AddNew
                rs.Fields("項目10") = 事務所
                rs.Fields("項目20") = strLine
                rs.Update
        End Select
    Loop
    mainStream.Close
    rs.Close
    MsgBox "end"
End Sub

からアクセスでデータ編集をし

10,事務所1,1,2,20,Aさん,4,5,6
10,事務所1,1,2,20,Bさん,7,8,9
10,事務所1,1,2,20,Cさん,10,11,12
10,事務所2,13,14,20,Dさん,16,17,18
10,事務所2,13,14,20,Eさん,19,20,21
10,事務所2,13,14,20,Fさん,22,23,24
10,事務所2,13,14,20,Gさん,25,26,27

のように項目10と項目20をキーに
一気に取り込むことで
解決しました。
ですがテストを重ねることで
配列やレコード数が大きくなると

データベース '' を開くことができません。アプリケーションで認識できないデータベースであるか、またはファイルが破損しています。となります。
修復をしたり色々検証はしましたが・・・
(他にも色々と問題がありこのままアクセスでの是正対応は考えておりません)

そこでエクセルVBAのデータ入出力に切り替えたいのですが
VBAの場合
どういった方法から
対応出来るか分かりません。
どなたかご教授頂けませんでしょうか。
どうぞよろしくお願いいたします。

補足
アクセスの問題で
項目10と項目20をキーに
取り込んでましたが
原型は
配列の添え字から
対応していました。

Sub main()

    Dim db As DAO.Database
    Dim rs(1) As DAO.Recordset
    Dim FSO As FileSystemObject
    Dim mainStream As TextStream
    Dim myData As Variant
    Dim 事務所 As String, i As Integer
    Dim cnt As Integer, vnt As Variant 
    Set db = CurrentDb
    Set rs(1) = db.OpenRecordset("テーブル", dbOpenDynaset) 'テーブルファイルをセット
    Set FSO = CreateObject("Scripting.FileSystemObject")
    Set mainStream = FSO.OpenTextFile("C:\testout.txt", ForReading)
    Do Until mainStream.AtEndOfStream
        myData = Split(mainStream.ReadLine, ",")
        Select Case myData(0)
            Case "10"
                事務所 = myData(0) & "," & myData(1) & "," & myData(2) & "," & myData(3)
                For i = 1 To 4
                    '?
                Next
            Case Else
                rs(1).AddNew

                cnt = 0
                For Each vnt In Split(事務所, ",")
                    rs(1).Fields(cnt) = vnt
                    cnt = cnt + 1
                Next
                For i = LBound(myData) To UBound(myData)
                    rs(1).Fields(i + cnt) = myData(i)
                Next
                rs(1).Update
        End Select
    Loop
    mainStream.Close
End Sub

< 使用 Excel:Excel2010、使用 OS:Windows7 >


こんにちは

>エクセルVBAのデータ入出力に切り替えたい

というのは、どういう意味なんでしょうか?

シート上に転記すればいいのなら、

Sub main()

    Dim FSO As New FileSystemObject
    Dim mainStream As TextStream
    Dim 事務所 As String
    Dim strLine As String
    Dim i As Long

    Set mainStream = FSO.OpenTextFile("C:\temp\testout.txt", 8)
    ReDim v(1 To mainStream.Line, 1 To 2)
    mainStream.Close

    Set mainStream = FSO.OpenTextFile("C:\temp\testout.txt", 1)
    i = 1
    Do Until mainStream.AtEndOfStream
        strLine = mainStream.ReadLine
        Select Case Split(strLine, ",")(0)
            Case "10"
                事務所 = strLine
            Case Else
                v(i, 1) = 事務所
                v(i, 2) = strLine
            i = i + 1
        End Select
    Loop
    mainStream.Close
    Range("A1").Resize(i, 2) = v
    MsgBox "end"
End Sub

こんな感じで出来ますか?

(ウッシ) 2016/08/16(火) 16:11


DAOは最近は(というかだいぶ前から)流行っていないため、ADOを使う方が良いかと思います。
ADOの方が汎用性が高い感じで、テキストデータでもExcelブックでもAccessでも一般的なDBサーバ各種でも扱えます。

とりあえず現状のままとして、エラーになるレコード数を確認してください。データを使う前に、RecordCountプロパティを見れば良いかと思います。

気になる点。
・rs(1)を宣言していますが、何故配列? しかも0番目は全く使っていないし…。
・整数型の宣言がInteger。これじゃ32767件までしか扱えませんよ? 普通はLong型にします。
(???) 2016/08/16(火) 16:52


(ウッシ)さん

サンプルデータありがとうございます。
>エクセルVBAのデータ入出力に切り替えたい
データを読み込んで(テーブルに読み込む際にエラーが発生)
データをはきだすという意味だったのですが
データ入出力できれば問題ありません。

アクセスに係わると
配列がいくつまで
レコードが何レコードまで
そもそもデータそのもののサイズとか
色々切り分けする部分が
ございます。
そのほかにも
色々な問題がありますので・・・

大量データですと
シート上に転記は難しいので
データをはき出す方向で考えております。
(フェンダー) 2016/08/16(火) 17:30


(???)さん
 コメントどうもありがとうございます。

 >とりあえず現状のままとして、エラーになるレコード数を確認してください

 今までの現状結果をまとめてから
 報告させていただきます。
(フェンダー) 2016/08/16(火) 22:10

 >・rs(1)を宣言していますが、何故配列? しかも0番目は全く使っていない し…。
 ・整数型の宣言がInteger。これじゃ32767件までしか扱えませんよ? 普通は Long型にします。

もうしわけございません。
こちらは原型という事で
テスト10件ぐらいでしか試しておらず
その他の検証もしていない原型でございます。

現状検証結果

1レコード 1300byte
10の値 17セル
20の値 157セル
250000レコード 
344MB

1レコード 5000byte
10の値 15セル
20の値 454セル
100000レコード 
434MB

上記サイズが、(実際の生データ)限界です。

(フェンダー) 2016/08/17(水) 08:46


Integer宣言が今回の問題とは無関係との事なので、置いておいて。

データ量がたしかにでっかいですねぇ。これは高速化のためにvという配列に値セットするというテクニックだと、メモリが足りなくなって、動かなくなりそうです。配列を使った高速化ができるのは、せいぜい数万件まででしょう。逆に、25万件までは動いたというのが凄いです。

どうしてもExcelで処理したいようですので、現状のコードを流用するとして、処理時間はかなり遅くなりますが、Application.ScreenUpdating = False による表示更新抑止だけにして、後は配列に代入せず直接セルに代入するように変えれば、データ量による問題はなくなると思います。

ですが普通に処理する場合、何十万件ものレコード数があるならば、無料のもので十分なので、DBサーバを構築すべきですね。やったことが無いと尻込みしがちですが、実はとっても簡単に環境構築できるのですよ。(面倒な事は全てDBサーバがやってくれます)
(???) 2016/08/17(水) 09:17


こんにちは

まだ要件が良く分からないのですが、
>データを読み込んで
>データをはきだす
というのは、結局は

テキストファイルを編集しながらAccessのテーブルに読み込むという事でしょうか?

AccessのVBAから、ExcelのVBAに変える意味が分からないです。

>シート上に転記は難しいので
>データをはき出す方向で考えております。

テキストファイルで出力するという事ですか?

(ウッシ) 2016/08/17(水) 09:49


(ウッシ)さん
ご説明は分かりにくくてもうしわけございません。

現状
テキストファイルを編集しながらAccessのテーブルに読み込む

希望
テキストファイルを読み込んで編集
テキストファイルで出力
になります。

AccessのVBAでもExcelのVBAでも
問題ないのですが
こちらが
エクセル学校という
掲示板でしたので・・・

(フェンダー) 2016/08/17(水) 10:14


こんにちは

配列は使わずに1行ずつ処理して出力していくとどうなりますか?

Sub test()

    Dim FSO As New FileSystemObject
    Dim mainStream As TextStream
    Dim outStream  As TextStream
    Dim 事務所 As String
    Dim strLine As String

    Set mainStream = FSO.OpenTextFile("C:\temp\testout.txt", 1)
    Set outStream = FSO.CreateTextFile("C:\temp\out.txt", 1)
    outStream.Close
    Set outStream = FSO.OpenTextFile("C:\temp\out.txt", 2)

    Do Until mainStream.AtEndOfStream
        strLine = mainStream.ReadLine
        Select Case Split(strLine, ",")(0)
            Case "10"
                事務所 = strLine
            Case Else
                outStream.WriteLine 事務所 & "," & strLine
        End Select
    Loop
    mainStream.Close
    outStream.Close
    MsgBox "end"
End Sub

(ウッシ) 2016/08/17(水) 10:36


(ウッシ)さん

コード提供ありがとうございます。

最初にご提示いただいた
シート上に転記のコードは
全く試していませんが

後から
ご提示いただいた
テキスト入出力コードでの
検証結果をお知らせいたします。

テストパターン1

テキスト入力前
1レコード 1300byte
10の値 17セル
20の値 157セル
500000レコード 
700MB

テキスト出力後
1レコード 1300byte
10の値 17セル
20の値 157セル
500000レコード 
1.16GB
所要時間 3分弱

テストパターン2

テキスト入力前
1レコード 5000byte
10の値 15セル
20の値 454セル
200000レコード 
1GB

テキスト出力後
1レコード 5000byte
10の値 15セル
20の値 454セル
200000レコード 
2GB
所要時間 3分弱

アクセスのテーブル読み込みより
安定して
動作できてます。

そのまま使用できるコードを
提示していただいて
恐縮です。
どうもありがとうございました。

(フェンダー) 2016/08/17(水) 19:37


(???)さん
 >ですが普通に処理する場合、
何十万件ものレコード数があるならば、
無料のもので十分なので、DBサーバを構築すべきですね。
やったことが無いと尻込みしがちですが、
実はとっても簡単に環境構築できるのですよ。
(面倒な事は全てDBサーバがやってくれます) 

アクセスに限界を感じましたから
データを管理できる有償ソフトを導入しました。
レコード数などは空きディスク容量など
ハードウェア的要因にのみ影響される以外は
2000000レコードでも入出力に非常に効率的な
アルゴリズムを利用しているため、データ処理が非常に高速です。
アドバイスどうもありがとうございました。

(フェンダー) 2016/08/18(木) 13:49


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.