AIと戦って、あなたの人生のリスク診断 >>

こんにちは。
EXCELのVBAにて巨大なファイルのデータを途中から読み込む方法がございましたらご教授いただきたいと思っています。

具体的には300万行ほどのCSVデータがありまして
たとえば、50万行目のデータを読み込みたい場合下記のようにすることにより、データの取得は可能なのですが、50万行目までSKIPするのに数秒の時間がかかってしまいます。いきなり50万行目からのデータを取得するようなスマートな方法は存在するのでしょうか。

よろしくお願いいたします。

Const ForReading = 1, ForWriting = 2, ForAppending = 3
Dim fs, f
Set fs = CreateObject("Scripting.FileSystemObject")
Set f = fs.OpenTextFile("C:\tmp.csv", ForReading, 0)

For w = 0 To 500000
f.skipline
Next

Debug.Print f.readline

f.Close

このQ&Aに関連する最新のQ&A

A 回答 (3件)

項目1 連番


項目2 名前
項目3 住所
3列の300万行データなら




'=========================
myDIR = "c:\happy"
myCSV = "ADO_EXCEL.csv"
mySQL = "SELECT * FROM " & myCSV & " WHERE 連番='500000'"
'=========================

Set myDB = CreateObject("ADODB.Connection")
myDB.Open "Driver={Microsoft Text Driver (*.txt; *.csv)};" & _
"DBQ=" & myDIR & ";" & "ReadOnly=1"
Set myRS = myDB.Execute(mySQL)
Do Until myRS.Eof = True
Msgbox "項目1 連番 :" & myRS(0)
Msgbox "項目2 名前 :" & myRS(1)
Msgbox "項目3 住所 :" & myRS(2)
myRS.MoveNext
Loop
myRS.Close : myDB.Close : Set myRS = Nothing : Set myDB = Nothing


http://www.jtw.zaq.ne.jp/kayakaya/new/kihon/text …
http://itpro.nikkeibp.co.jp/article/COLUMN/20070 …
http://itpro.nikkeibp.co.jp/article/lecture/2006 …
Excelで扱うことができる限界は 
シートの行数が決めるのではありません
使う人の知識がExcelでできることを決定します
Excel2000でも100万件データを扱うことはできます
シートを使わずデータ処理を行うブックもあります
質問者は シートの行数を問題にしていません
シーケンシャルであることも条件にしていません 
できる できない は知識によって違います
最短 最適 は別の条件もあります

この回答への補足

大変的確な回答ありがとうございます!
まさに求めていた手法でした。
CSVにもSQLを使うことができるんですね。知りませんでした。
これは大変便利です。しかもかなり高速に動作しました。

私の利用したいCSVにはヘッダーが存在しませんでしたので、少し調べてみました。
HDR=No と指定することにより、フィールドをF1、F2などとして利用できると書いてあったのですが
Microsoft Text Driver では正常に動作しませんでした。
Microsoft.Jet.OLEDB.4.0 を利用することにより動作しました。

参考まで正常に動作したコードを書いておきます。

'=========================
myDIR = "C:\temp"
myCSV = "test.csv"
mySQL = "SELECT TOP 2 * FROM " & myCSV & " WHERE F2 = '4034';"
'=========================

Set rs = CreateObject("ADODB.Recordset")
Con = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & myDIR & ";" & _
"Extended Properties=""text;HDR=No;FMT=Delimited;"";"

rs.Open mySQL, Con, 0

Do Until rs.EOF = True
MsgBox "項目1 :" & rs(0)
MsgBox "項目2 :" & rs(1)
rs.MoveNext
Loop

rs.Close: Set myRS = Nothing

補足日時:2007/10/09 00:15
    • good
    • 3

http://www.happy2-island.com/vbs/cafe02/capter00 …
SQLを使うことで 目的のレコードを抽出することができます
できれば レコードにそれぞれ最初から連番を付けて
その連番で50万行目を呼び出せば 1件だけ表示できます
この方法なら他の条件での検索もできるので便利です
分からなければ サンプルを用意します 補足してください
    • good
    • 0

エクセルと言っているが、エクセルやエクセルVBAと関係を持たせるのは無理です。

たとえ2007でも。制限行数をオーバーしてます。
エクセルだから早くできるかも知れないと想像するとことは、ディスクの読み書きの早さで、MS社のエキスパートだから特別のテクニックを弄していると思うのかもしれないが、不明です。
ですからプログラムはVBでの方法ということになるが、CSVファイルはレコード(各行に当たる)長が一定している保証はないので、順次読むしかなく、50万件目から、あるいは番号500001から処理をいきなり始めるなど絶対無理です。
前もって固定長でランダム読み出しのファイル形式の場合は、可能です。
後尾にスペースを無理に持たせて一定長のレコードを作る手はあるかもしれないが、まあそうはしませんね。
ーー
アクセスでも、「量的に」可能かどうかわかりませんが、エクセル
VBAより可能性はありそう。
ーー
シーケンシャル読み出し
ランダム読み出し
ファイル構造
各種データベース
などを勉強して考えてください。
ーー
時代につれ、ディスクの読み取りスピードアップがなされ、それが寄与するが、今日明日のことにならない。
ーー
50万行を即時に処理し無ければならない業務とはどんなものかな。
>数秒の時間がかかってしまいます
数秒ですむというのも信じがたいが、それが辛抱できないのでしょうか。
何か初心者が思いついた一本線のロジックでつっ走っているような
印象なんだが。
ディスクからメモリに読み込まないと50万件目はわからないし、
CSVファイルは、順読み出ししか方法がないし、VBなど言語やデータ処理ソフトの中でも、質問の方法は単純で早い方法とおもう。
ーー
この処理はどういう場面で出てくるのか、問い合わせの都度か、分析などして数回限りで終るのか書いてないのも、前もって別ファイルを処理できる機械が与えられるのか書いてないのも片手落ちです。
ただし
繰り返し問い合わせなどがあるので、前もって検索などに適したファイル構造にCSVを変換しておき
 (1)前もって時間を使いー>問い合わせ時に回答が早い
その回はデータは全体の1単位しか使わない。
 (2)1回・数回限り
 (3)定例バッチ処理(応答・完了処理に時間を取れる)
データは通常全部を対象にする。
 (4)毎回CSVファイルから処理する
などあるが、(1)はデータベースソフトを使って、プロの領分です。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
imogasi様のご回答では「絶対無理」とのことでしたが、他の方が的確な回答をしてくださいました。

後学のためご参考にされることをお勧めします。

ありがとうございました。

お礼日時:2007/10/09 00:27

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QエクセルVBA 大容量CSVファイルの読み込み

200万行のCSVファイルをエクセルに読み込みたいです。Rows.Countを超えるので、2回に分けて
半分読み込み
処理
残り半分読み込み
処理
のようにしたいのです。どうすればいいでしょうか?

参考までに、検索したところ下記のQ&Aは見つかりました。
https://oshiete.goo.ne.jp/qa/3407338.html
ただ、これは途中の任意の1行を読み込む方法です。

100万行のファイルを2個作る等のようなとんちの利いた回答はナシでお願いします。
他に無ければしますが。。。

Aベストアンサー

使えそうな項目が無いですね・・・。
ExcelでCSVファイルを読み込むときに頭を悩ませるデータ型の変更、
(電話番号の前ゼロ消失、
郵便番号が日付になったり計算されてしまう・・・が無さそうなのでマシかも)

CSVファイルのフルパスが
D:\SampleData\てすと.csv
で、
タイトル行が無い場合のコードです。パスとファイル名は適宜書き換えてください。
20行程度の小さなテストデータで問題なかったら本番でお試しを。
数分かかるかと思います。

Sub Test()
Dim Cn As Object
Dim Rs As Object
Dim i As Long, k As Long, j As Integer

Set Cn = CreateObject("ADODB.Connection")

With Cn
.Provider = "Microsoft.ACE.OLEDB.12.0"
.ConnectionString = _
"Data Source=D:\SampleData;" _
& "Extended Properties='text;HDR=NO;" _
& "FMT=Delimited'"
.Open
End With

Set Rs = CreateObject("ADODB.Recordset")
Rs.CursorLocation = 3 'adUseClient
Rs.Open "SELECT * FROM てすと.csv", Cn, 0, 1, 1

MsgBox "項目数は" & Rs.Fields.Count _
& vbNewLine _
& "行数は" & Rs.RecordCount

Application.ScreenUpdating = False
Sheets(1).Range("A1").CopyFromRecordset Rs, 10 '←本番では1000000に

'残りはシート2に
Rs.absolutePosition = 11 '←本番では1000001に
Do Until Rs.EOF
k = k + 1
If k > 1048576 Then
MsgBox "最大行数を超えました。もう無理!"
Exit Do
End If
For j = 1 To Rs.Fields.Count
Sheets(2).Cells(k, j) = Rs.Fields(j - 1)
Next
Rs.movenext
Loop
Application.ScreenUpdating = True
Rs.Close: Set Rs = Nothing
Set Cn = Nothing
End Sub

使えそうな項目が無いですね・・・。
ExcelでCSVファイルを読み込むときに頭を悩ませるデータ型の変更、
(電話番号の前ゼロ消失、
郵便番号が日付になったり計算されてしまう・・・が無さそうなのでマシかも)

CSVファイルのフルパスが
D:\SampleData\てすと.csv
で、
タイトル行が無い場合のコードです。パスとファイル名は適宜書き換えてください。
20行程度の小さなテストデータで問題なかったら本番でお試しを。
数分かかるかと思います。

Sub Test()
Dim Cn As Object
Dim Rs As Object
Dim...続きを読む

Q【VBA】テキストファイルを指定行数からの読み込み

こんばんは。

EXCEL VBAでテキストファイルを読み込む事について質問です。

VBAでテキストファイルをこちらから指定する行数(上から何番目という感じで)からデーターを読み込みたいのですが、どの関数をつかっていいかわからず困っています。
1行ずつ読みこむ「Input Line関数」では、無駄な行まで読み込むので動作が遅くなります。
読み込みたい行はすでにわかっているので、最初からその行に飛んでからデーター読み込みたいと思ってます。

ちなみに指定する行数は、ファイルによって違います。
あらかじめ「Input Line関数」で、ある文字が何行目にあるかを探す行為をあらかじめ行っています。

みなさまのアイデアを拝借したく、よろしくお願いします。

Aベストアンサー

速度は分かりませんが、これとか
http://officetanaka.net/excel/vba/filesystemobject/textstream10.htm

あるいは、丸ごと読みこんで、改行コードでSplitして、文字列配列を相手に該当行検索も含めて処理するとか。
昨今のPCでは、相当大きなテキストファイルでもメモリー内で処理できると思います。
http://officetanaka.net/excel/vba/filesystemobject/textstream07.htm

テキストファイルの構造によってはADOで処理する案も考えられますが、Recordsetにはファイルの先頭から(あるいは末尾先頭で)入っている事が保証されているのか、ちょっと心配。参考URLはCSVになっていますが、タブ区切りテキストファイル(拡張子.txt)でもいけます。
http://home.att.ne.jp/zeta/gen/excel/c04p47.htm

以上ご参考まで。

QエクセルVBA 大容量CSVファイルの読み込みが遅い

800万行、1.4GBのCSVファイルをLineにより100万行ずつシートに読み込み、処理してます。
100万行読み込み
コンマを区切り文字にして展開
データ処理
次の100万行読み込み
の手順です。

出だしは快調で1シート20秒程度で読み込みます。ところが、シートを重ねるごとにだんだん遅くなり、1シート5分、最後の方はメモリーオーバーでエラーとなり、最後まで行き着いてません。ウインドウ下枠に表示される「フィル」で時間がかかります。その後で表示される「区切り位置」以降、データ処理は普通です。おそらくLineによる読み込みで時間がかかっていると思います。なぜでしょうか?どうすればいいでしょうか?

エラー位置はDoの3行下です。
Sub Macro1()

Dim vFile As Variant
Dim WSdata As Worksheet
Dim ffn As Long
Dim vA() As Variant
Dim j As Long, k As Long

Const Half As Long = 500000 ' 1回の書き出し行数
Const CROWSZ As Long = 1000000 '1シートへの書き出し数
vFile = ThisWorkbook.Path & "\CSVconverted.CSV"

ReDim vA(1 To UnitRead, 1 To 1)

'100万行を入力するワークシート
Set WSdata = ThisWorkbook.Worksheets("CSV")

'CSVファイルを開く
ffn = FreeFile()
Open vFile For Input As #ffn

j = 1
k = 1
Do
Line Input #ffn, vA(j, 1)   '1行ずつ読み込み
If j >= Half Or EOF(ffn) Then
WSdata.Cells(Rows.Count, "A").End(xlUp).Offset(1, 0).Resize(UBound(vA), 1).Value = vA 'ここで止まる。vAにマウスを当てると「メモリーオーバー」と表示
ReDim vA(1 To UnitRead, 1 To 1)
j = 0

If k >= CROWSZ Or EOF(ffn) Then
      'コンマを区切り文字にして展開
With WSdata.Range(WSdata.Cells(2, "A"), WSdata.Cells(Rows.Count, "A").End(xlUp))
Application.DisplayAlerts = False
.TextToColumns .Cells(1), xlDelimited, Comma:=True
Application.DisplayAlerts = True
End With
k = 0


'データ処理がここに記載


WSdata.Cells.ClearContents
End If
End If
j = j + 1
k = k + 1
Loop While Not EOF(ffn)
Close #ffn 'CSV閉じる

End Sub

800万行、1.4GBのCSVファイルをLineにより100万行ずつシートに読み込み、処理してます。
100万行読み込み
コンマを区切り文字にして展開
データ処理
次の100万行読み込み
の手順です。

出だしは快調で1シート20秒程度で読み込みます。ところが、シートを重ねるごとにだんだん遅くなり、1シート5分、最後の方はメモリーオーバーでエラーとなり、最後まで行き着いてません。ウインドウ下枠に表示される「フィル」で時間がかかります。その後で表示される「区切り位置」以降、データ処理は普通です。おそら...続きを読む

Aベストアンサー

No.4ママチャリです。
まず①の件ですが、確かに Office 2013 and later となっていますね。でも、私の環境もExcel2010ですが、ヘルプにも掲載されているし、実際、StartRowで指定した行から読み込めています。各種ホームページを見ても2013より前のバージョンでも話題になっているので、問題ないと思います。

②の方ですが、OverTheGalaxyさんが書いたコード(Workbooks.OpenText Filename:=vFile, DataType:=xlDelimited, startrow:=ReadRow, comma:=True)を実際に動かしたところ、正常に動きました。確かにstartrowは大文字になりませんでしたが・・・。

試しに、[ファイル]ー[開く]の手順をマクロに記録し、それをベースに実験してみてはいかがでしょうか。各種HPを見ていて、「省略可能なパラメータと書いてあるくせに、省略したら問題が発生した」みたいな記事がありましたので・・・。

マクロを記録する際、列数が多いと FieldInfo パラメータがあふれることがあります。ただ、形式を指定する必要がなければ、不要なものなので捨てちゃってOKです。

では、ご検討をお祈りします。
それにしても、同じ環境(2010ではやっていないのでしたっけ?)で動作が異なるとは、Micr●s●ftらしいですね。

No.4ママチャリです。
まず①の件ですが、確かに Office 2013 and later となっていますね。でも、私の環境もExcel2010ですが、ヘルプにも掲載されているし、実際、StartRowで指定した行から読み込めています。各種ホームページを見ても2013より前のバージョンでも話題になっているので、問題ないと思います。

②の方ですが、OverTheGalaxyさんが書いたコード(Workbooks.OpenText Filename:=vFile, DataType:=xlDelimited, startrow:=ReadRow, comma:=True)を実際に動かしたところ、正常に動きました。確かにstar...続きを読む

QMicrosoft VBAで2GBを超えるファイルサイズのバイナリデータを読み込みたい。

Windows 7で Excel 2010 のVBAを使い、あるアプリケーションの出力結果 (バイナリデータ) が正しいかチェックしようとしています。
その結果が 2GBバイト以下の場合はうまくチェックできており、実績があります。
ところが 2GBを超えると下記の Get文で「レコード番号が不正です」というエラーメッセージが出て中断してしまいます。
おそらく Get文の VBA内部のポインタが Long型で、オーバーフローしてしまうのだと想像しています。

Dim a(1024) As Byte
Dim d as double

Open "バイナリデータ.dat" For Binary Access Read As #1
For d = 1 To ((1024 * 1024) * 10) ' 10GBファイルを1KBずつ読み込みするループ処理
Get #1, , a

'~ a の内容チェック処理 (略します) ~

Next d
Close #1

なお、実績のあるチェック処理は、そのまま使いたいので他の言語は利用したくないと思っています。
(会社なので、VB や VC を購入するにも、稟議の日数がかかってしまうのです)

別の試みで Get の代わりに INPUTB()関数を、試してみましたがバイナリデータにヌル &H0 などが含まれているので、読み込みができません。
(それは INPUTB()関数の仕様のようです)

なにか良い解決方法をご存じの方がいらっしゃいましたら、宜しくおねがいします。

Windows 7で Excel 2010 のVBAを使い、あるアプリケーションの出力結果 (バイナリデータ) が正しいかチェックしようとしています。
その結果が 2GBバイト以下の場合はうまくチェックできており、実績があります。
ところが 2GBを超えると下記の Get文で「レコード番号が不正です」というエラーメッセージが出て中断してしまいます。
おそらく Get文の VBA内部のポインタが Long型で、オーバーフローしてしまうのだと想像しています。

Dim a(1024) As Byte
Dim d as double

Open "バイナリデータ.dat" Fo...続きを読む

Aベストアンサー

#1です。
#1のF.ReadBytesでは、
F.ReadBytes内でByte型をVariant型に変換し、F.ReadBytesの戻り値をVariant型からByte型
に変換しています。
上記のデータの転送は、ファイルのサイズが大きくない場合は、それほど問題になりませんが、
ファイルサイズが今回のように大きい場合は、それなりの遅延原因になります。
その為、以下のReadBytes2を作成してみました。
以下のコードをRandomクラス内に追加してください
----------------------------------------------
Public Function ReadBytes2(ByVal ByteCount As Long, ByRef ReadBuff() As Byte) As Long
Dim BytesRead As Long
If hFile = INVALID_HANDLE_VALUE Then
RaiseError W32F_FILE_ALREADY_CLOSED
End If
ReadFile hFile, ReadBuff(LBound(ReadBuff)), ByteCount, BytesRead, 0
ReadBytes2 = BytesRead
End Function
----------------------------------------------
ReadBytes2の第1引数が読み込みサイズ、第2引数が、読込バッファ
戻り値が実際に読み込んだデータのサイズ(バイト)になります。
戻り値が0の場合は、ファイル終端を意味します。
第2引数の読込バッファは、必ず第1引数の値以上のサイズを確保してください。
以下、実際の呼び出しプログラム側です。
----------------------------------------
Sub Macro2()
Dim buff(1023) As Byte
Dim endFlag As Boolean
Dim datalen As Long
Dim amari As Long
Dim readCount As Long
Dim i As Long
Dim st As Single
Dim et As Single
Dim F As Random
Set F = New Random
F.OpenFile "c:\\goo\\File10GB"
endFlag = False
amari = 0
st = Timer
Do While endFlag = False
datalen = F.ReadBytes2(1024, buff())
If datalen < 1 Then
endFlag = True
End If
If endFlag = False Then
readCount = readCount + 1
For i = 0 To datalen - 1
amari = (amari + buff(i)) Mod 256
Next i
End If
Loop
F.CloseFile
Set F = Nothing
et = Timer
Debug.Print "時間2(秒)=" + CStr(et - st)
Debug.Print "読込件数=" + CStr(readCount)
Debug.Print "余り=" + CStr(amari)
End Sub
-------------------------------------------------
1024バイト単位で読み込むため、
Dim buff(1023) As Byte を宣言しています。
以下実行結果です。
時間2(秒)=332.0859
読込件数=10485760
余り=236

#1の実行時間は約530秒でしたので、6割程度に時間が短縮されたことがわかります。
ReadBytes2を使用することを推奨します。

#1です。
#1のF.ReadBytesでは、
F.ReadBytes内でByte型をVariant型に変換し、F.ReadBytesの戻り値をVariant型からByte型
に変換しています。
上記のデータの転送は、ファイルのサイズが大きくない場合は、それほど問題になりませんが、
ファイルサイズが今回のように大きい場合は、それなりの遅延原因になります。
その為、以下のReadBytes2を作成してみました。
以下のコードをRandomクラス内に追加してください
----------------------------------------------
Public Function ReadBytes2(ByVal ByteCo...続きを読む

QEXCEL VBAマクロ作成で、他のEXCELからデータを取り込みたい

メインプログラム(EXCEL VBA)より、
他のフォルダーにあるEXCELの項目の内容を取り込みたいです。
たとえば他のフォルダーのEXCELのRange("A2:A3").ValueをメインプログラムのRange("C2:C3").Valueにセットしたい時です。

・コマンドボタン押したら、どこのEXCELから取り込むかのポップアップ(?)は、表示はできてます。
・作業者が選んだパスとブックもMsgBoxで表示できてるので、もらう相手の場所も取得できてます。

・となると次はOPEN,INPUTですか?
テキストデータの取り込みですと、Inputでそのバッファを定義してるのですが、なんか違うような。。。

よろしくお願いします!

Aベストアンサー

私がやる方法です。

Dim writeSheet As Worksheet ' 自分自身の書き出し先シート
Set writeSheet = ThisWorkbook.Worksheets(1) ' Sheet1 を参照

Dim readBook As Workbook ' 相手ブック
Set readBook = Workbooks.Open(filename) ' 相手ブックを開いて参照
Dim readSheet As WorkSheet ' 相手シート
Set readSheet = readBook.Worksheets("sheetName") ' 相手シートを参照
' または Set readSheet = readBook.Worksheets(sheetIndex)

' 例えば
writeSheet.Cells(1, 1).Value = readSheet.Cells(2, 2).Value ' 相手シートの B2 の値を自分自身の A1 に書き込む

readBook.Close False ' 相手ブックを閉じる
Set readSheet = Nothing
Set readBook = Nothing

私がやる方法です。

Dim writeSheet As Worksheet ' 自分自身の書き出し先シート
Set writeSheet = ThisWorkbook.Worksheets(1) ' Sheet1 を参照

Dim readBook As Workbook ' 相手ブック
Set readBook = Workbooks.Open(filename) ' 相手ブックを開いて参照
Dim readSheet As WorkSheet ' 相手シート
Set readSheet = readBook.Worksheets("sheetName") ' 相手シートを参照
' または Set readSheet = readBook.Worksheets(sheetIndex)

' 例えば
writeSheet.Cells(1, 1).Value = readSheet.Ce...続きを読む

QExcelのメモリ(配列)の上限は2Gではないのか

こんにちは、
現在ExcelのVBAで大量に配列を必要なマクロを作成しています。

その為、計算量が増えるとどうしても、
メモリ不足というエラーが発生してしまい困っています。

そこで、現在使っているExcelがどれだけの配列とメモリを使用できるのか
下記コードを使用してテストしてみました。

そうすると、下記のような値の時メモリ不足というエラーが発生してマクロが終了しました
(下図参照)
・メモリ(プライベートワーキングセット)  :1249716 K (約1G?)
・String型配列数(各要素"01,02,03,04,05,06") :約28000000(2800万個)

私の知識では、32bitアプリケーションのメモリの上限は2Gだと聞いています。
ですが、実際にはその半分しか使われていません。
そこで質問となるのですが

・32bitアプリケーションの上限が2Gと言われているのはプラベートワーキングセットの値のことではないのか?

・32bit版Excelを使用して、これ以上のメモリ(配列)を使用することは可能か

・可能であれば、その方法はどんな方法か?

以上のことについてお聞きしたいと思っております。
上のどれか一つでもいいです。知っていることがあれば教えてください。

補足となりますが、テストしたPCの簡単な環境を下に記載して置きます。
どのPCでも上記結果とほぼ変わりはありませんでした。

PC1
Windows7 32bit メモリ 4G Excel2013(32bit)

PC2
Windows7 64bit メモリ 8G Excel2010(32bit)

以下は使用したプログラムコードです

---------------------------------------------------------------


Public Sub 配列上限取得計算()
On Error GoTo ErrEnd
Dim i As Long
Const kankaku As Long = 1000000


Dim Moji As String
Moji = "01,02,03,04"

Dim ans() As String
ReDim ans(1 To kankaku) As String
i = 1
Do
If i Mod kankaku = 0 Then
ReDim Preserve ans(1 To i + kankaku) As String
End If

ans(i) = Moji
i = i + 1
Loop
Erase ans
Exit Sub
ErrEnd:
MsgBox Err.Description & vbCrLf & "これ以上の配列を設定できません。" & vbCrLf & "上限は" & i & "です。"
Erase ans
Err.Clear

End Sub

こんにちは、
現在ExcelのVBAで大量に配列を必要なマクロを作成しています。

その為、計算量が増えるとどうしても、
メモリ不足というエラーが発生してしまい困っています。

そこで、現在使っているExcelがどれだけの配列とメモリを使用できるのか
下記コードを使用してテストしてみました。

そうすると、下記のような値の時メモリ不足というエラーが発生してマクロが終了しました
(下図参照)
・メモリ(プライベートワーキングセット)  :1249716 K (約1G?)
・String型配列数(各要素"01,02,03,04,05...続きを読む

Aベストアンサー

#2の回答者です。
>何百万どころか数千万単位で必要です。
>やっていることは、50個あるサンプルで複数の実験を行います。

そういう理由で、配列を使うという所に疑問を感じます。

>50個あるうち6個の組み合わせを考えた場合、
>15890700(1589万700個)通りの文字列を一度配列に格納し、それから各条件に合うかどうか各要素ごとに確認していく作業をしています

時々、ここの掲示板でも、年に一度ぐらい、似たような話は出会いますが、果たして一覧を配列の中にすべて収める必要があるのでしょうか?その都度、組み合わせていって、必要なものを取り出せば済む話だと思うのです。まさか、出来上がってみなければ分からないというような話ではないと思います。もちろん、人間の判断を要するものだとしても、1500万件もの量を、個人でこなしきれるものではないとは思います。

何十年と、こうした掲示板を見ている私でも、組み合わせをすべて配列に入れるという話は、初めてです。もちろん、#1の人の書いた、配列の分散という方法もあるはずだとは思うのですが、今度は、本体のExcel側が果たして要求に応えるか分かりません。

ただし、Excelのアドインの"Solver"の開発元の会社のツールで、組み合わせを解決するという話は聞いたことがあります。ただ、10数万円もするアプリですので、容易には手が出ません。その代わり、VB6時代で、いくつかのアルゴリズムは公開されているはずです。

#1のお礼欄
>64bitOfficeはまだ一般的でなく、また、32bitOfficeと同時にインストールはできなかったと記憶しております。

64bit Officeは、現在の最新バージョン(2013)でも、Microsoft 側は、使用をお勧めしていません。

#2の回答者です。
>何百万どころか数千万単位で必要です。
>やっていることは、50個あるサンプルで複数の実験を行います。

そういう理由で、配列を使うという所に疑問を感じます。

>50個あるうち6個の組み合わせを考えた場合、
>15890700(1589万700個)通りの文字列を一度配列に格納し、それから各条件に合うかどうか各要素ごとに確認していく作業をしています

時々、ここの掲示板でも、年に一度ぐらい、似たような話は出会いますが、果たして一覧を配列の中にすべて収める必要があるのでしょうか?その都度、組...続きを読む

QVBAでの100万行以上のデータの取り込み

どなたかご教示お願いいたします。
VBAで100万行以上のCSVデータの取り込みは可能でしょうか?
初心者なのでファイルを開いてセルに入れてから範囲を指定し配列に
取り込み処理しておりましたが100万行以上だとデータがシートから出てしまいます。
なのでエクセルに展開せずに配列に取り込むなどということはできるのでしょうか?
もし可能であればあつかましいのですが、A列の120万行データを配列に取り込むサンプルをご教示いただけるとありがたいのですが・・・
よろしくお願いいたします。

Aベストアンサー

6割程度出来たかも?
データ数180万、項目数8個、最大・最少を求めるのは1項目、
100データ区切りで試した結果。
5分。
200データ区切りだと
4分。
最初の30秒ほど応答なし状態ですがその後にシート転記が始まりました。
700万だとExcelが落ちる可能性有りです。

ただ、まだ確認したいことがありますのでコードは差し控えます。
時間軸の項目名と書式(例 15:30:25 のようなもの)。
時間軸のデータは重複があり得ますか。
何の最大値・最小値なのでしょう?もしかして時間軸を除く16項目。
もしかして、200区切りでその範囲内なら時間軸の値は同じ?
(でないと16項目の最大・最少を求めても意味ないですよね)
200区切りで、もし一部分でも200に満たないものがあった場合に
考慮しないで常に200区切りとして処理しても構わない。

呑み込みが悪くてすみません。
出来ればデータを1行目から数行提示してもらえると助かります。
例えば3データ区切とした場合
時間軸|項目1|項目2|・|項目16
1:01:01  10   20    30
1:01:01  20   50    40
1:01:01  15   80    10
1:01:02  90   60    10
1:01:02  20   50    40
1:01:02  15   80    50

1:01:01  20   80    40
1:01:01  10   20    10
1:01:02  90   80    50
1:01:02  15   50    10
ということでしょうか?
横の方が良いのか
1:01:01 20/10  80/20  40/10
1:01:02 90/15  80/50  50/10

つまり、
時間軸が大体200区切りで値が同じ
その中でそれぞれの項目の最大・最少なら単純なのですけど。
冒頭のデータ量で2分程度でした。
(3年前の中堅スペックのPCです)
700万行だとやってみないことには…。
ヘッダー(タイトル行)は120も700のモノも同じ
でデータ部分が異なるだけ?
bin-chan さんにお任せして敵前逃亡しようかな。。。

6割程度出来たかも?
データ数180万、項目数8個、最大・最少を求めるのは1項目、
100データ区切りで試した結果。
5分。
200データ区切りだと
4分。
最初の30秒ほど応答なし状態ですがその後にシート転記が始まりました。
700万だとExcelが落ちる可能性有りです。

ただ、まだ確認したいことがありますのでコードは差し控えます。
時間軸の項目名と書式(例 15:30:25 のようなもの)。
時間軸のデータは重複があり得ますか。
何の最大値・最小値なのでしょう?もしかして時間軸を除く16項目。
...続きを読む

QEXCELファイルのカレントフォルダを取得するには?

EXCELファイルのカレントフォルダを取得するには?

C:\経理\予算.xls

D:\2005年度\予算.xls

EXCEL97ファイルがあります。

VBAで
  カレントフォルダ名
(C:\経理\,D:\2005年度\)
を取得する事は可能でしょうか?

CURDIRでは上手い方法が見つかりませんでした。

Aベストアンサー

こんばんは。
Excel97 でも、同じですね。以下で試してみてください。

Sub test()
'このブックのパス
a = ThisWorkbook.Path
'アクティブブックのパス
b = ActiveWorkbook.Path
'Excelで設定されたデフォルトパス
c = Application.DefaultFilePath
'カレントディレクトリ
d = CurDir
MsgBox "このブックのパス   : " & a & Chr(13) & _
   "アクティブブックのパス: " & b & Chr(13) & _
   "デフォルトパス    : " & c & Chr(13) & _
   "カレントディレクトリ : " & d & Chr(13)
End Sub

QEXCEL VBA で現在開いているブックのファイル名を取得する方法

EXCEL2003 VBAで業務を簡素化するために、現在開いているブックのファイル名を取得する方法が分かりません。
作業手順をマクロを使って処理していますが、オリジナルのワークブックをファイル名を変えて保存し、以後、このワークブックを読み込んで使用しています。
このときのVBAは、オリジナルのファイル名を使っているため、ファイル名を変更するとエラーになり、以後の業務に使用できません。
常にファイル名を取得出来るVBAをどなたか、教えて下さい。

Aベストアンサー

>現在開いているブックのファイル名
 ちょっと曖昧な表現かなぁという気もいたしますが、VBAが書いてあるブックのブック名は
ThisWorkbook.Name
で、現在 "アクティブにして" 操作対象になっているブックの名前は
ActiveWorkbook.Name
ですね。

 しかし、
>VBAは、オリジナルのファイル名を使っているため、ファイル名を変更するとエラーになり
というような文脈からすると、
ThisWorkbook.Name
の方ですかね。

Qエクセル マクロで指定フォルダを開く

エクセルにて
指定フォルダを開く、マクロがあれば教えて頂けないでしょうか。
よろしくお願いいたします。

Aベストアンサー

こんにちは。

こういうものですか?
開くフォルダを変えたいときは targ に与えるパスを変更します。

Sub OpenFolders()
Dim targ As String
targ = "C:\"
Shell "C:\Windows\Explorer.exe " & targ, vbNormalFocus
End Sub


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング