毎日更新されるCSVファイルがあります。
このファイルをExcelに変換して、他のファイルにリンクしています。
CSVファイルを開かなくても、データを更新できるよう、マクロを組みました。
Excel2000では、問題なく動くのですが、’97で実行すると、
実行時エラー '1004': アプリケーション定義またはオブジェクト定義のエラーと出てしまいます。
メインに使っているPCが'97なので、
色々調べてみたのですが、私の知識ではわからず、困っています。
詳しい方がいらっしゃれば、教えて頂きたく思います。
コードは以下のようなものです。
Private Sub Workbook_Open()
Dim Workbooks As Variant
Dim Sheets As Variant
Dim Filename As Variant
Dim wR As Long
ThisWorkbook.Sheets("Sheet1").Activate
Cells.ClearContents
Filename = Application.GetOpenFilename("CSV ファイル(*.csv),*.csv")
ここで、デバック
↓
With ActiveSheet.QueryTables.Add _
(Connection:="TEXT;" & Filename, Destination:=Range("A1"))
.TextFileCommaDelimiter = True
さらにここでも、デバック(実行時エラー1004 外部データ範囲を
更新するためのテキスト ファイルが見つかりません)
↓
.Refresh BackgroundQuery:=False
End With
With ActiveSheet
.Columns("B:C").Delete shift:=xlToLeft
'(CSVファイルのA,B列は不要のため、削除)
wR = .Range("B" & Rows.Count).End(xlUp).Row
.Range("A1") = "=B1&C1&D1"
.Range("A1").AutoFill Destination:=Range("A1:A" &wR), Type:=xlFillDefault
End With
End Sub
No.6ベストアンサー
- 回答日時:
追伸:
#換えればよいだけです
ちょっと、バカなことを書いてしまいました。(^^;
ではなくて、統一してしまえばよいです。
>#If numVer = 8 Then 'ディレクティブ
> LineBuf = ex97Split(TextLine, DELIM)
> #Else
> LineBuf = Split(TextLine, DELIM)
>#End If
↓
LineBuf =ex97Split(TextLine,DELIM)
としてしまってください。
No.5
- 回答日時:
こんにちは。
やはり、ダイレクティブがうまく行っていないようですね。初めて使うワザだったので、私は、勉強不足でした。その部分は、勉強しなおします。今回には、間に合いそうにはありませんが、前の文章に触れていましたが、直し方は、簡単です。
> LineBuf = Split(TextLine, DELIM)
> ↑ここが反転
その反転したものを、
LineBuf = ex97Split(TextLine, DELIM)
に換えればよいだけです。一応、97では確認済みです。
No.4
- 回答日時:
こんにちは。
一応、こちらで、その後で、Excel 97 に通して可動は確認しました。
私は、なるべく、標準モジュールに、これらを入れてあったほうが負担が少ないと考えていますが、もう一度調べてみます。
>>LineBuf = ex97Split(TextLine, DELIM)
>の Split が反転した状態でエラーになるとのことでした。
この意味が、もう少し複雑な状況かもしれません。厳密にどこの部分なのかはっきりすればよいのですが、そうでないと、探すのに苦労します。
それで、だめなら、もう一度、ダイレクティブ(#IF)分岐で、コードの完全分離に切り替えます。
この回答への補足
こんばんは。
お返事が遅くなってしまい、大変申し訳ありません。
(別のファイルで悪戦苦闘してしまったので、こちらのファイルになかなか取り掛かれませんでした)
本日、自分で試してみたところ、
「sub 又は functionが定義されていません」
とエラーが出てしまいました。
#If numVer = 8 Then 'ディレクティブ
LineBuf = ex97Split(TextLine, DELIM)
#Else
LineBuf = Split(TextLine, DELIM)
↑ここが反転
何かまだ、設定の足りないものや、省略しない方が良い
コードがあるのでしょうか?
社内にはマクロのわかる人がいない為、Wendy02さんのご回答のおかげで何とかやっていけている状況です。
お手隙の時でも構いませんので、どうぞ宜しくお願い申し上げます。
No.3
- 回答日時:
こんばんは。
今回のマクロは、私のとってはやはり難しかったです。初めて使うワザもあります。
初めて使うワザやお蔵入りのワザがうまく動くかどうかです。なんと言っても、Val 関数も97でないことに気がつきました。本当は、ちゃんと97をインストールしたほうがよいとは思うのですが、そのためには、今までの上位バージョンをアンインストールしなければならないのです。うまくいかなければ、また、手直しするつもりです。
それから、ご自身で作られたものかはわかりませんが、
>Dim Workbooks As Variant
>Dim Sheets As Variant
これは、絶対いけません。Excel VBAを知らない人で、VBを書く人に時々見られる変数ですが、エラーにはならないのですが、予約語として考えたほうがよく、それを使ったら、場合によっては、そのオブジェクトを殺してしまいます。
なお、ex97Split だけでも、上位バージョンで動くはずです。ただ、Split 関数よりも、多少処理スピードが遅いのです。
>Wendy02さんが、OpenText や QueryTables は、相性の良くないコードだから、あまり使わない方が良いと書かれていた解答は目にしていたのですが、
私が書いたのは、ひとつは引数を確証なく省略すると失敗することがあると書いたのと、QueryTable を貼り付けた後は、その内部のQueryTable を削除したほうが後々処理に困らない、と書いたのです。
そういう私は、ここ1年半ぐらいは、QueryTables を使ってお終いにすることもあります。理由は、皆が自分の手でマクロを書けるように願い、記録マクロを使って、ちょっと加工するだけで、こんなものが出来ることを分かってもらうために書いています。
中には、バカにされたと誤解する人もいるようですが、結果が同じなら、少しぐらい処理スピードが遅くても、簡単なほうがよいと思います。Visual Basic のように難しい書き方よりも、VBAは、VBAの書き方があってもよいのではないか、と思っています。そんな私でも、今回のように避けられない時もあります。
'ThisWorkbook モジュール
'------------------------------------------------
Private Sub Workbook_Open()
Call CSVImportMacro
End Sub
'標準モジュール
'------------------------------------------------
Sub CSVImportMacro()
Dim FName As String
Dim Fno As Integer
Dim TextLine As String
Dim numVer As Integer 'ディレクティブIfの外で取るため
Dim LineBuf As Variant
Dim Ub As Integer
Dim i As Long
Const DELIM As String = "," '区切り文字
Const START As String = "B1" 'B1 から
Const LINESTART As Integer = 3 '3列目から
With ActiveWorkbook.Worksheets("Sheet1")
.Activate
.UsedRange.ClearContents
FName = Application.GetOpenFilename("CSV ファイル(*.csv),*.csv")
If StrComp(FName, "False") = 0 Or FName = "" Then Exit Sub
Fno = FreeFile()
Open FName For Input As #Fno
Do Until EOF(Fno)
Line Input #Fno, TextLine
TextLine = Application.Substitute(TextLine, """", "") 'Quotationを取る
numVer = Left$(Application.Version, 2)
#If numVer = 8 Then 'ディレクティブ
LineBuf = ex97Split(TextLine, DELIM)
#Else
LineBuf = Split(TextLine, DELIM)
#End If
Ub = UBound(LineBuf)
If Ub > LINESTART - 1 Then
LineBuf = IndexLineArray(LineBuf, LINESTART - 1) '配列なので、-1
Ub = UBound(LineBuf)
.Range(START).Offset(i).Resize(, Ub).Value = LineBuf
i = i + 1
End If
Loop
Close #Fno
.Range("A1", .Range("B65536").End(xlUp).Offset(, -1)).FormulaLocal = "=B1&C1&D1"
.Range("A1").EntireColumn.AutoFit
End With
End Sub
Private Function IndexLineArray(ByVal BaseArray, Optional StartCol As Integer = 0, Optional EndCol As Integer = 0)
'配列切り分け BaseArray =配列, StartCol スタート列(-1), EndCol =終了列(-1)
Dim v As Variant
Dim i As Integer
Dim Ar() As Variant
Dim cnt As Integer
cnt = 0
For Each v In BaseArray
If cnt >= StartCol And EndCol = 0 Then
ReDim Preserve Ar(i)
Ar(i) = v
i = i + 1
ElseIf cnt >= StartCol Then
If cnt <= EndCol Then
ReDim Preserve Ar(i)
Ar(i) = v
i = i + 1
End If: End If
cnt = cnt + 1
Next v
IndexLineArray = Ar()
End Function
Private Function ex97Split(TextLine As Variant, Optional DELIM As String = ",")
'Excel97 用Split関数
Dim OutPutArray() As Variant
Dim LineLength As Integer
Dim i As Long
Dim FirstLocate As Integer
Dim FindLocate As Integer
Dim WordLen As Integer
Dim QtFind As Integer
Dim QtNetFind As Integer
Dim QtFlg As Boolean
LineLength = Len(TextLine)
If LineLength = 0 Then Exit Function
FirstLocate = 1
Do
QtFind = InStr(FirstLocate, TextLine, Chr(34))
FindLocate = InStr(FirstLocate, TextLine, ",")
If FindLocate = 0 Then
If Len(Mid$(TextLine, FirstLocate)) > 0 Then
ReDim Preserve OutPutArray(i)
OutPutArray(i) = Mid$(TextLine, FirstLocate)
End If
Exit Do
End If
If QtFlg Or QtFind = 1 Then
QtNetFind = InStr(QtFind + 1, TextLine, Chr(34))
WordLen = QtNetFind - QtFind - 1
ReDim Preserve OutPutArray(i)
OutPutArray(i) = Mid$(TextLine, QtFind + 1, WordLen)
FirstLocate = QtNetFind + 2
QtFlg = False
Else
WordLen = FindLocate - FirstLocate
ReDim Preserve OutPutArray(i)
OutPutArray(i) = Mid$(TextLine, FirstLocate, WordLen)
FirstLocate = FindLocate + 1
End If
'オプショナル
If QtFind = 2 Or FindLocate + 1 = QtFind Then
QtFlg = True
End If
i = i + 1
Loop
ex97Split = OutPutArray()
End Function
この回答への補足
こんなに複雑なコード、ありがとうございます。
その他の点につきましても、丁寧に教えて頂き、感謝この上ありません。
自分の使っているPC(2000)では、正常動作しました。
'97がインストールされているPCが私の勤務時間中、空かなかったので
手が空いたら、試してくれるようお願いしておいたところ、
>LineBuf = ex97Split(TextLine, DELIM)
の Split が反転した状態でエラーになるとのことでした。
ただ、実行して頂いた方は、ほとんどBVAは知らないので、
エラーメッセージの内容も、確認できていない状態です。
せっかくコード書いて頂いたのに、すみません。
明日、自分でもう一度試してみて、結果をご報告したいと思います。
少々、ご猶予下さいませ。
No.2
- 回答日時:
こんばんは。
>Cells.ClearContents の後ろに入れてみましたが、
「実行時エラー424 オブジェクトが必要です」が出てしまいます。
これは、ActiveSheet.Cells.ClearContents とかしないと、ThisWorkbookなどは、ローカル・オブジェクトとしてのシートが存在しません。
ですが、簡単だと思っていたら、今、間違いに気が付きました。
Workbooks.OpenText _
これでは、そのファイル自体を開けてしまうことですね。それをコピーしなければならないのでは、話が違ってしまいます。私は、97用のこの内容のコードはギブアップしたことがあり、97で、この関連のコードは、それ以来何年も試したことがありません。
まず、配列のSplit関数が97にはないので、自分で作らなくてはなりません。上位バージョンで作って、最後に97に入れてみないと、一体、どこがエラーが出るか分からないのです。これは、私には、この部分を中途半端に知っているだけに大変な内容です。以前は、定番だったこのコードも、今は、見られないコードです。
それに、ExcelのVersion によってコードを換えるプログラムを書かなくてはなりません。統一的なコードは出来ません。甘く見すぎていました。少し、時間をください。
この回答への補足
こんばんは。
>甘く見すぎていました<いえ、甘く見ていたのは、私の方です。
部分的に少しだけ書き換えれば済むものと思っていました。
Wendy02さんが、OpenText や QueryTables は、相性の良くないコードだから、あまり使わない方が良いと書かれていた解答は目にしていたのですが、VBAに取り組んで1ヶ月あまりの私には、他のコードの書き方がわからず、行き当たりばったり的にマクロを組んでいました。
>配列のSplit関数が97にはないので、自分で作らなくてはなりません。
このことも全く知らず、お恥ずかしい限りです。
お手数をかけてしまって、本当に申し訳ありません。
やりたいことは、QNo.3084424 のままです。
この、ExcelファイルのA列(関数式)をVlookupの検索値として、他のファイル使用しています。
今のところ、問題なく検索できているので、もしかしたら、文字列で取り出す必要はないのかもしれません。
(たまたま、探し出したコードに、文字列を取り出すコードが含まれていため、そのまま引用してしまいました。)
バージョンの違いで、これほど大変なことになるとは、思いもかけないことでした。
大変なご迷惑とは思いますが、どうぞよろしくお願い致します。
No.1
- 回答日時:
こんばんは。
Excel 97 で、
>ActiveSheet.QueryTables.
というのは可能なのでしょうか?97にはなかったはずです。
単に、Workbooks.OpenText Filenames:= ......
で、TextQualifier を決めてあげる方法で出来たはずです。
その部分を交換すれば、出来ると思います。
この回答への補足
ご回答ありがとうございます。
>ActiveSheet.QueryTables
が'97でないということは、知りませんでした(汗)
甘えてしまって申し訳ないのですが、
>Workbooks.OpenText Filenames
はどのように設定したら、良いのでしょうか?
Cells.ClearContents の後ろに入れてみましたが、
「実行時エラー424 オブジェクトが必要です」が出てしまいます。
(意味がわかっていなくて、ネット上から探してきたコードを貼り付けていますので、不要なものも入っているかと思いますが…)
Workbooks.OpenText _
Filename:=Flname, _
StartRow:=1, _
DataType:=xlDelimited, _
TextQualifier:=xlTextQualifierDoubleQuote, _
ConsecutiveDelimiter:=False, Tab:=False, _
Semicolon:=False, Comma:=True, _
FieldInfo:=Array(Array(1, 1), Array(2, 1))
↑
今のコードでは、後でAB列を削除しているのですが、(ExファイルのA列には数式を設定、B列以降にデータ貼り付け)
必要なのはCSVファイルのC:H(数字ですが、頭の00も抽出したいため)ですので、必要な列だけを選択するコードが入れられれば、いいと思うのですが、このコードがどこを指しているのが、理解していないままです。
なさけないこと、この上ないのですが、教えて頂ければ幸いです。
どうぞお願い致します。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) 複数のcsvファイルをExcelに一括変換したい 2 2023/03/03 12:44
- Excel(エクセル) エクセルのVBAについて とあるサイトのコードを参考に、CSVの文字化けを直すVBAを作成しているの 7 2022/11/04 14:15
- Visual Basic(VBA) 複数csvを横に追加していくマクロについて 2 2023/04/25 09:19
- Visual Basic(VBA) エクセルのマクロを使ってメールを送る方法について教えてください 2 2022/03/29 01:36
- Visual Basic(VBA) まとめシートから集計シートへA列のコードが一致したら1行コピーするマクロをネット上で見つけました。こ 1 2022/08/30 14:11
- Visual Basic(VBA) vbaのエラー対応(実行時エラー7:メモリが不足しています) 4 2023/04/24 00:20
- Excel(エクセル) Excel VBAどこが間違ってますか? 4 2023/07/17 10:04
- Visual Basic(VBA) エクセル VBA 処理スピードを上げたいのですが。 6 2023/03/31 20:52
- Visual Basic(VBA) フォルダの場所を可変にしたいです(マクロ) 4 2023/05/11 10:00
- Visual Basic(VBA) Csvファイルの最終行を取得する構文はこれであっていますか?オブジェクトは、このプロパティまたはメソ 3 2022/12/26 14:38
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
PowerShellを使って関連付けら...
-
fcloseで発生するエラーについて。
-
Returnに対するGoSubがありません
-
Access2013にてドラッグ&ドロ...
-
NAS上のファイルの使用中が解除...
-
アクセスのクエリでコンパイル...
-
DisplayAlertsブロパティで ”実...
-
ファイルクローズ(fclose)でエ...
-
「パス名が無効です」の発生原因
-
「複数の選択範囲に対して実行...
-
エクセルマクロでエラーの原因...
-
VBでファイルが開かれているか...
-
ACCESS VBAでのインポート
-
DBへのコネクションタイムアウト
-
ワークブックに名前をつけて保...
-
CSVファイルが開かれているかど...
-
MATLABの2つのプログラム間でデ...
-
batファイルでレジストリキーの...
-
VB6 Dir関数で52エラー発生
-
画像読み込み失敗の判定
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBでファイルが開かれているか...
-
batファイルでレジストリキーの...
-
gccを行ってもexeファイルが生...
-
「パス名が無効です」の発生原因
-
Returnに対するGoSubがありません
-
アクセスのクエリでコンパイル...
-
NAS上のファイルの使用中が解除...
-
VBから参照できないCのDLLを使...
-
PowerShellを使って関連付けら...
-
Adobeのプレミアプロの書き出し...
-
EXCELのVBAでWORDが開いてある...
-
FTPの送信結果を検知したい
-
access テキストボックスの値取得
-
エクセルマクロでエラーの原因...
-
【COBOL】read文でエラー
-
VB6 Dir関数で52エラー発生
-
VBA ExecuteExcel4Macro 型が一...
-
Access2013にてドラッグ&ドロ...
-
freadでデータがない場合の読込...
-
ファイルクローズ(fclose)でエ...
おすすめ情報