
マクロ1では元々存在するold.csvファイルを上書きしています。
old.csvはテキストエディタを使い、手で作ったファイルです。
マクロ2では、マクロ1で上書きされたold.csvファイルを読み込み
データが終了するまで処理します。
この時、old.csvは存在するのに
実行時エラー '3021'
BOFとEOFのいずれかがTrueになっているか、または現在のレコードが削除されています。
要求された操作には、現在のレコードが必要です。
となります。
どなたか解決していただけないでしょうか?
Excel2003 SP3です。
どうかよろしくお願いします。
マクロ1
FilePass = "c:\Documents and Settings\デスクトップ\old.csv"
A_CONcsv = "Driver={Microsoft Text Driver (*.txt; *.csv)}; " & _
"DBQ=c:\Documents and Settings\デスクトップ;" & _
"ReadOnly=1"
Call Old_data_UP(StrOld_data, A_CONcsv)
'old.csvファイル出力
Open FilePass For Output As #1
Print #1, StrOld_data
Close #1
Function Old_data_UP(FStrOld_data, CONcsv)
new_x.csvを読み込みold.csvを更新するための編集をしています。
(old.csvは最初だけ手で作り、次からはマクロ1で更新された物を使いたいです。)
省略します。
End Function
マクロ2
FilePass = "c:\Documents and Settings\デスクトップ\new_x.csv"
A_CONcsv = "Driver={Microsoft Text Driver (*.txt; *.csv)}; " & _
"DBQ=c:\Documents and Settings\デスクトップ;" & _
"ReadOnly=1"
A_CONxls = "Driver={Microsoft Excel Driver (*.xls)}; " & _
"DBQ=c:\Documents and Settings\デスクトップ\db\Mydata.xls;" & _
"ReadOnly=1"
Call data_match(StrNew_x, A_CONcsv, A_CONxls)
'new_x.csvファイル出力
Open FilePass For Output As #1
Print #1, StrNew_x
Close #1
Function data_match(FStrNew_x, CONcsv, CONxls)
new.csvとold.csvとMydata.xlsを読み込み
new_x.csvを出力するための編集をしています。
new.csvはテキストエディタを使い、手で作ったファイルです。
省略します。
End Function
No.4ベストアンサー
- 回答日時:
>Excelでマッチングしてファイル出力
普通「マッチング」のロジックでは、EOF判定は重要です。
比較する2ファイルのレコード数は同じですか?、違いますよね?。
簡単に言えば、
ファイル1:あ、い、う、お
ファイル2:あ、う、え
ファイル2の「え」、ファイル1の「う」の後は、
共にどういうロジックか、です。
ファイル1の「お」のときの比較対象であるファイル2はEOFになってしまってます。
これと似た感じでしょう。
どんなロジックにしたかは分かりませんが、
EOFになったときの処置を中心に見たら良いかと思います。
原因箇所がつかめたら、「マッチング」のロジックの見直しでしょう。
>ファイル1の「お」のときの比較対象であるファイル2はEOFになってしまってます。
これと似た感じでしょう。
このアドバイスを元に、Debug.Printをあちらこちらに入れて見直しをした結果
原因がわかりました!
やはりnew.csvは値が表示されているのに
old.csvは値が空白で表示され、2件目以降を読み込むことなく
new.csvが先にEOFになっていました。
new.csvが先にEOFにならないことを前提にロジックやテストデータを作っていますので
テストデータがおかしいのでは?と思い、テキストエディタで開いて見てみました。
今まで出力結果をExcelで開いて確認していたのでわからなかったのですが
old.csv更新時、空白行が最後に付加されて出力されていました。
FStrOld_data = FStrOld_data & ID,名前,キャリア,点数,所属 & Chr(10)
と編集してから一括で出力していたので余計な空白行が付加されたようです。
そして、所属,IDの昇順でデータを読んでいるのでold.csvの1件目の値が空白で表示されたようです。
FStrOld_data = FStrOld_data & Chr(10) & ID,名前,キャリア,点数,所属
と変えることで正常に処理されるようになりました。
長くて読みずらいロジックを全部載せることができたら
もっと早く解決できたのではないかと思います。
時間を割いて回答をくださいまして
本当にありがとうございました。
No.6
- 回答日時:
原因つかめないから他のやり方で、これもどうかと思いますが。
ロジック見直しは当然として、
ファイル番号を同じ#1でなく変えてみる。
ファイルは最後にはクローズ出来ているか。オープンしたままのロジックはないか。
マクロ実行1回目はOKだが繰り返した2回目はおかしいか。
OLDを更新しないケースなら実行前後で同じファイル構造になっているはず。
見る観点はあります。
No.5
- 回答日時:
期待する回答は得られないので、こちらの考え方で書いてみました。
どれほどの技術かは分かりませんが、そのままで、ADODBを使うのは無理だと思います。なお、ご質問のエラーは、適当なファイルがないか、コードを間違えているということです。Sub TestMacro()
Dim mPath As String, oldFile As String, xlsFile As String, newFile As String
Dim fNum As Integer, orgNum As Integer, i As Long
Dim TextLine As String, rn As String, mArray As Variant
Dim wb As Workbook, sh As Worksheet
Dim myArray As Variant
'必ず、mPath は。末尾に\ を後に入れる
mPath = "C:\Documents and Settings\デスクトップ\"
oldFile = "001.csv"
xlsFile = "aa01.xls"
newFile = "n001.csv"
'csvのインポート
If Dir(mPath & oldFile) = "" Or Dir(mPath & xlsFile) = "" Then MsgBox "ファイルが用意されていません。", 48: Exit Sub
With Application
orgNum = .SheetsInNewWorkbook
.SheetsInNewWorkbook = 1
End With
Set wb = Workbooks.Add
With wb
fNum = FreeFile()
Open mPath & oldFile For Input As #fNum
Application.ScreenUpdating = False
Do While Not EOF(fNum)
Line Input #fNum, TextLine
i = i + 1
myArray = Split(TextLine, ",")
ActiveSheet.Cells(i, 1).Resize(, UBound(myArray) + 1).Value = myArray
Loop
Close #fNum
Application.ScreenUpdating = True
Set sh = .Worksheets.Add(After:=.Worksheets(.Worksheets.Count))
End With
'シートのインポート
With Workbooks.Open(mPath & xlsFile)
.Worksheets(1).Cells.Select
.Worksheets(1).Cells.Copy sh.Cells
.Close False
End With
With wb
Set sh = .Worksheets.Add(After:=.Worksheets(.Worksheets.Count))
rn = .Worksheets(2).Range("A1").CurrentRegion.Address(0, 0)
With sh
'結合の数式
.Range(rn).Formula = _
"=IF(AND(Sheet1!RC<>"""",Sheet2!RC<>""""),Sheet2!RC,IF(Sheet1!RC="""",Sheet2!RC,Sheet1!RC))"
.Range(rn).Value = .Range(rn).Value
'出力
fNum = FreeFile()
Open mPath & newFile For Output As #fNum
For i = 1 To .Range(rn).Rows.Count
mArray = Application.Transpose(.Range(rn).Rows(i).Value)
mArray = Application.Transpose(mArray)
Print #fNum, Join(mArray, ",")
Next i
Close #fNum
End With
End With
wb.Close False
Beep
Application.SheetsInNewWorkbook = orgNum
End Sub
No.3
- 回答日時:
>特に参考にしたのは下記のサイトです。
リンクで紹介された方法は方法は知っています。それは、どちらかというと、Excelが得意でない人用だと思います。仮に便利だと思っても、Excelには、ADODBは、標準装備していませんから、参照設定しても、インスタンスを生成するので、オーバーヘッドが掛かってしまいます。例えば、Excelファイルでは扱えないような巨大なファイル(例:郵便番号.csv)の時に利用するのが一般的だと思っています。
私が始めて見たというのは、二つのConnection オブジェクトを比較する方法が見えてこないのです。ある程度の確信があってしているのだろうから、それなりのロジックを持っているはずだと思いました。だから、逆にご質問をしたわけです。
>BOFとEOFのいずれかがTrueになっているか、
ここの、RecordSet の部分でエラーが発生しているのだろうと思います。そこは書かれていません。
>ExcelやCSVをDB感覚で使えたら良いのにな、という思いから
ということですから、ADODB(Jet)を利用する方法は変えられないとすれば、手が付きません。私の個人的なアドバイスとしては、今の方法は、可能であるという自信がなければ、辞めたほうがよいのではないかと思います。
Fields の数もあるかと思いますから、拾い出す手間もあります。
Line Input なら、Split 関数で引き出すことは出来ますが、Fields はオブジェクトですから、一括では出来ません。
Function data_match(FStrNew_x, CONcsv, CONxls)
別に、コードを出さなくてもよいけれども、そのロジックが分からないのです。Connectionオブジェクトを与えているなら、その後で、RecordSet があるはずです。ロジックというのは、今回の場合、比較する方法ということです。その比較する方法が分からないのです。1対1にしなければ比較できませんから、一旦、配列に置いているのでしょうか?
仮に達成できたとしても、比較はテキストベースで行うので、思った以上に、分かりにくく無駄な部分が多くなるのではないかと思います。また、xls側のファイルは、そのまま変換も出来ませんから、シートに上げるのが早いような気がします。だったら、最初から、CSVのテキストもしく、ワークシート上で比較する方法をすべきではないのかなって思います。
>仮に達成できたとしても、比較はテキストベースで行うので、思った以上に、分かりにくく無駄な部分が多くなるのではないかと思います。
はい。かなり無駄が多いと思います。
ですから、たいした処理ではないのに入力文字数制限でマクロ1本分すら載せられないのです。
私が知っている範囲で期待する処理結果を得るためには、ADOでデータを取得して処理する方が早く
趣味で使うマクロなので、処理速度が遅かったり、ロジックに無駄が多かったりしても良いと思いました。
今、CSVデータの件数が約500件、Excelデータの件数が約1500件で処理をしています。
今後、CSVデータの件数が約1000件、Excelデータの件数が約10000件になることを予想しています。
今のままでは処理速度が遅くて使い物にならなくなる気がします。
もっと勉強して、教えていただいたコードのように
データをシート上に展開して処理するよう新たに作りたいです。
時間を割いてサンプルコードまで載せてくださいまして
本当にありがとうございました。
また質問させていただくことがあると思います。
どうぞ、よろしくお願いします。
No.2
- 回答日時:
本当に、Excelなのでしょうか。
そういう手法が出来るのですか?何か参考資料があるのだろうと思いますが、私は、始めて見ました。よほど、そういう手法を得意としているなら、それ自体にこちらは何も言えないけれども、ただ、質問の際には、もう少し詳しく説明してほしいです。ADODB.Connection で両方を読み込み、それを比較するなどという技術は、BOFとEOFとは、片方がバイナリで片方がテキストファイルですから、当然、比較したら、そのようなエラーの現象は分かるのですが、その比較のロジックが理解できません。
>new.csvとold.csvとMydata.xlsを読み込みnew_x.csvを出力するための編集をしています。
Excelを持っていらっしゃるなら、new.csv をシートにExcel上に上げて、Mydata.xlsの特定のシートを、どのように処理するかは知りませんが、それで比較すればよいのではないかと思います。
ただ、例えば、old.csv のA1には値が入ってい、B1 が空の状態で、 new.csvが、A1が空で、B1が入っている状態で、 new_x.csvは、A1, B1のセルに値が入っているものにする場合などは、少なくとも、ワークシート上でもなかなか難しいものではないかと思います。そういう規則性をきちんと組み立てているのでしょうか。
あえて、Jet を利用するというのは、データ・サイズそのものが違うはずですから、それなりの確信がなくてはとても手が出せるものではないと思います。
>Function data_match(FStrNew_x, CONcsv, CONxls)
>new.csvとold.csvとMydata.xlsを読み込み
>new_x.csvを出力するための編集をしています。
>new.csvはテキストエディタを使い、手で作ったファイルです。
>省略します。
>End Function
ここは、どういうロジックを使っているのでしょうか?
もう少し、詳しい内容が必要だと思います。
>本当に、Excelなのでしょうか。そういう手法が出来るのですか?何か参考資料があるのだろうと思いますが、私は、始めて見ました。よほど、そういう手法を得意としているなら、それ自体にこちらは何も言えないけれども、ただ、質問の際には、もう少し詳しく説明してほしいです。
ExcelやCSVをDB感覚で使えたら良いのにな、という思いから
自分専用でこのマクロを作りました。
Excelでマッチングしてファイル出力なんて強引だ、ということもわかっています。
特に参考にしたのは下記のサイトです。
http://www.happy2-island.com/access/gogo03/capte …
質問するにあたり、入力文字数制限の関係でいろいろ省略してしまいました。
説明不足で申し訳ありません。
時間を割いて回答をくださいまして
ありがとうございました。
No.1
- 回答日時:
デバッグしましょう。
1行ずつやれば、どこで何が起きているか、エラーの原因は多少でも見えてきます。
デバッグできないなら、質問の前にデバッグを学習する。
デバッグした結果、old.csvは存在するのに実行時エラーが発生しているのではないか?
と思いました。
説明不足で申し訳ありません。
マクロ2
old.csvとnew.csvの差分をnew_x.csvに出力しています。
new.csvのみにデータが存在する場合、Mydata.xlsにそのデータが存在するか見ています。
マクロ1
new_x.csvのデータがMydata.xlsに存在するかを見てold.csvを出力しています。
old.csvは既に存在するファイルなので上書きされます。
マクロ2、マクロ1の順序で実行し、期待通りに出力していることを確認しました。
再度、マクロ2を実行すると実行時エラー '3021'が発生しました。
そこで、マクロ1実行前に避けておいたold.csvで上書きして
マクロ2を実行するとエラーはなく、期待通りに出力していました。
マクロ1でold.csvを上書きすることによって、old.csvが認識できなくなっているのでは?
と思いました。
質問するにあたり、入力文字数制限の関係でいろいろ省略してしまいました。
上記の質問内容で説明は足りるかな、と不安でしたが
やはり説明不足でした。
時間を割いて回答をくださいまして
ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) 複数のcsvファイルをExcelに一括変換したい 2 2023/03/03 12:44
- Excel(エクセル) エクセルのVBAについて とあるサイトのコードを参考に、CSVの文字化けを直すVBAを作成しているの 7 2022/11/04 14:15
- その他(プログラミング・Web制作) データ解析ソフトRでのファイル入力read.csvがエラーになります 7 2022/03/27 22:11
- Excel(エクセル) CSVファイルでVBAを動かす方法 3 2023/04/04 10:22
- Visual Basic(VBA) エクセルVBAについて 8 2022/07/13 22:41
- Excel(エクセル) 【マクロ】webアドレスにて指定されたCSVファイル【excelソフト表示】を印刷する件 1 2023/02/15 01:52
- Visual Basic(VBA) 複数csvを横に追加していくマクロについて 2 2023/04/25 09:19
- Excel(エクセル) エクセルでcsvファイルを開いてVBAを使いたい 7 2022/04/28 11:12
- Visual Basic(VBA) マクロを教えてください。 7 2023/06/01 19:47
- その他(プログラミング・Web制作) Fortranでの出力ファイル 2 2023/03/21 21:25
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
複数エクセルファイルの合成
-
エクセルのVBAについて とある...
-
Python CSVファイルについて
-
csvファイルを結合するバッ...
-
FTPコマンド mgetでとまってし...
-
アクセスと同フォルダのCSVファ...
-
【Rコマンダー】データインポー...
-
大量のフォルダからひとつのフ...
-
コマンドプロンプトのエラーに...
-
Windows System32 Security Hea...
-
「営業秘密の漏洩」について
-
コマンドプロンプトの「%1」と...
-
バッチでテキストファイルから...
-
.txtではなく.logの方が良いの...
-
これってパソコンの最適化が完...
-
一括でフォルダと同じ名前にフ...
-
リンクの張り付けかたを教えて...
-
名前の変更ができない動画ファイル
-
バッチファイル 文字列にスペ...
-
binファイルを解凍したいの...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エクセルのVBAについて とある...
-
複数エクセルファイルの合成
-
Python CSVファイルについて
-
アクセスと同フォルダのCSVファ...
-
複数のcsvファイルを統合、でも...
-
【Rコマンダー】データインポー...
-
FTPコマンド mgetでとまってし...
-
エクセル 指定範囲をCSV出力
-
MAC フォルダ内のPDF件数とペー...
-
csv形式からbmpを作成
-
csvファイルを結合するバッ...
-
コマンドによるzip圧縮
-
gnuplotで複数csvファイルから...
-
エクセルマクロ、複数のCSVファ...
-
Excelでcsvファイルをエクスポ...
-
Dosから既存フォーマットのエク...
-
複数のCSVファイルを読み込んで...
-
csvをVBAを使ってエクセル形式...
-
csvファイルをlinuxコマンドで...
-
VBA でCSV集計
おすすめ情報