![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?5a7ff87)
マクロ独学で勉強中です。
検索しましたが、下記コードしか自分では組めず、最終手段で質問いたします。
【やりたいこと】
1.フォルダ内のすべてのcvsファイルの作成日時を確認。
2.現在の日付から直近三日間で作成されたファイルを判別。
3.判別されたcsvファイルを新規ファイルの1列目から順にコピー。
それぞれのcsvファイルにはA1からQ1までデータが入力されています。
フォルダ内にあるcsvファイル数は5000ほどあり、下記のマクロですべて取り込んでそこから日付で判別していくとなると時間がかかります。
(いちいち開いてこぴーしてるというのもあると思いますが、、、)
ちなみに、csvファイルの名前は、”○○0414○○○.csv" みたいに一応日付がファイル名として記載されています。
このファイル名から判別できるとよりありがたいです。
(作成日時だと意図しないものもコピーされる恐れがあるため)
どなたかご教授いただければ幸いです。
Sub test()
Const FolderPath As String = "C:TestFolder"
Dim Filename As String
Dim Sh0 As Worksheet, Sh As Worksheet
Dim c As Long
Set Sh0 = ActiveSheet
Filename = Dir(FolderPath & "\*.csv")
Do Until Filename = ""
c = c + 1
Set Sh = Workbooks.Open(FolderPath & "\" & Filename).Sheets(1)
Sh.Range("A1:Q1").Copy Sh0.Range("A" & c & ":Q" & c)
Application.DisplayAlerts = False
Sh.Parent.Close
Application.DisplayAlerts = True
Filename = Dir()
Loop
End Sub
No.6ベストアンサー
- 回答日時:
#3#5は独学中とのことですのであえて
処理部分を分け、配列に入れています。
ファイルのフルパスを取得する所で#5の処理を入れても良いと思いますが
エラー対策などの事もあるのでこのようロジックもなんとなく、、知っておいた方が良いと思います。
横から失礼しますが、ちなみにご質問2のファイル名で操作する場合、
#3のコード
Do While fileName <> "" から Loopまでを
Do While fileName <> ""
Set TrgFile = fso.GetFile(FolderPath & "\" & fileName)
'該当ファイルを配列に入れる (ここの箇所で条件をファイル名のxxなどにする事などが出来ます
' If TrgFile.DateLastModified > DateAdd("d", -3, Now) Then
If IsNumeric(Mid(fileName, 3, 4)) Then
If Int(Mid(fileName, 3, 4)) >= Int(Format(Now() - 3, "mmdd")) Then
ReDim Preserve Array_file(i)
Array_file(i) = TrgFile.path
i = i + 1
End If
End If
fileName = Dir()
Loop
のように書き換えると
試してないので少し自信はないのですが、
ファイル名の3文字目から7文字目に対応できると思います。
コード内の不要なコメント行は、消してください。
返事が遅くなり申し訳ありません。
正常に動作しましたのでベストアンサーに選ばせていただきました。
動作確認は済んだので、内容の理解と、追加コードは自分で記述していこうと思います。
今回のマクロを組むうえで、最難関と感じていたのが今回の箇所でしたので、迅速かつ正確なコードをご提示いただき大変助かりました。
その他の皆さんも回答して頂きありがとうございました。
No.9
- 回答日時:
>Dim d1 As Date, d2 As Date, d3 As Date, dd As Date
宣言する型は日付型ではなく文字列型(As String)ではないでしょうか?
No.8
- 回答日時:
コピペでうっかり見逃していたのですが、、
Const FolderPath As String = "C:TestFolder"
は
Const FolderPath As String = "C:\TestFolder"
ですね。
No.7
- 回答日時:
初級者ジジィなので的外れも良い所かもですけど。
別の言語で該当するCSVファイルを1つに纏め、そのファイルからエクセルに取り込めば宜しいのでは?
と希望内容を見ているとそう感じます。
とは言え他言語なんて『?』なジジィですので、カテゴリーを絞り込み過ぎない程度で質問をしてみるとか?
No.5
- 回答日時:
#2#3です
Array_file配列には該当ファイルのフルパスが入るので
' 配列内のデータを取り出す(ここでファイルを開く処理)
の下部分から、、最後まではこんな感じで良いかと
Dim n As Long
Dim wS As Worksheet
Set wS = ActiveWorkbook.ActiveSheet
For i = 0 To UBound(Array_file)
n = wS.Cells(Rows.Count, "A").End(xlUp).Row + 1
Application.ScreenUpdating = False
With Workbooks.Open(Array_file(i))
With ActiveSheet
wS.Range(wS.Cells(n, 1), wS.Cells(n, 17)).Value = .Range(.Cells(1, 1), .Cells(1, 17)).Value
End With
.Close Savechanges:=False
End With
Application.ScreenUpdating = True
' Msg = Msg & Array_file(i) & vbCr
Next
' 配列内のデータを取り出す--終わり
Exit Sub
NothingFile: '以降、該当ファイルが無い場合の処理
MsgBox ("該当ファイルはありません")
End Sub
調べても分からない点がありましたら、補足かお礼で
No.4
- 回答日時:
No1です。
>一つずつ開いてするのは非効率
どうなさりたいのでしょうか?
どうするのが効率的とお考えなのでしょうか?
ご質問文にご提示のコードでは、フィルタもかけずに全部のファイルを開いてコピペしていますけれど、そこに関しては何のコメントも無いようです。
仮に、フィルタをかけるとして、それからどうしたいのでしょうか?
まぁ、CSVを全部読み込まずに、テキストとして最初の1行だけ読み込むという方法もあるとは思いますけれど、対象のCSVがどのような内容のものなのかにもよるでしょうし、そもそものご提示のコードがそのような方法はとっていませんでしたので・・・
いずれにしろ、ファイルを開いて読み込むことには変わりないはずです。
例えば、ScreenUpdatingを停止しておくことで、それなりに早くはなると思いますけれど・・・?
>上記のコード追加して実行しましたが、延々ループとなってしまいました。
No1で提示した処理は、ループには直接関係がないものです。
ループを繰り返すのは、(多分)どこかループに関係のある制御を誤って変えてしまったものと想像されます。
例えば、
Filename = Dir()
の1行を削除してしまったとか・・・?
No.3
- 回答日時:
つけ忘れ テストプロシージャ
Sub TestSample()
Const FolderPath As String = "C:TestFolder"
Dim FileName As String, Extension As String
Dim Array_file() As String
Dim fso As Object, TrgFile As Object
Dim Msg As Variant
Dim i As Long
Extension = ".csv" '対象拡張子
Set fso = CreateObject("Scripting.FileSystemObject")
FileName = Dir(FolderPath & "\*" & Extension)
Do While FileName <> ""
Set TrgFile = fso.GetFile(FolderPath & "\" & FileName)
'該当ファイルを配列に入れる
'(ここの箇所で条件をファイル名のxxなどにする事などが出来ます
If TrgFile.DateLastModified > DateAdd("d", -3, Now) Then
ReDim Preserve Array_file(i)
Array_file(i) = TrgFile.Path
i = i + 1
End If
FileName = Dir()
Loop
Set TrgFile = Nothing
'該当ファイルフルパスを配列に入れる--終わり
On Error GoTo NothingFile '配列空用エラー対策
' 配列内のデータを取り出す(ここでファイルを開く処理)
For i = 0 To UBound(Array_file)
Msg = Msg & Array_file(i) & vbCr
Next
' 配列内のデータを取り出す--終わり
MsgBox Msg
Exit Sub
NothingFile: '以降、該当ファイルが無い場合の処理
MsgBox ("該当ファイルはありません")
End Sub
No.2
- 回答日時:
こんにちは、
2のファイル名から判定する方法はすでに回答がありますので
1,の作成日の確認と更新日が3日以内のファイルを取得する方法です。
また、ご質問の背景は分かりませんが、ファイル名に日付以外の部分で
共通カテゴリー名などが付いていれば、更新日時から最新のファイルのみを抽出する事も可能と思います。
ファイルの作成日時や更新日時、アクセス日時を取得する方法は、
FileSystemObject(ファイルシステムオブジェクト)を使用します。
参考 http://officetanaka.net/excel/vba/filesystemobje …
作成日時の場合は、DateCreatedプロパティを取得します。
更新日時の場合は、DateLastModified
アクセス日時の場合は、DateLastAccessed
下記は、フォルダー内にあるcsvファイルの更新日が3日以内のファイルpathをを取得するプロシージャです。(時間も関係するので仮要件)
取得できたファイルpathは配列に入れています。
(データ(取得)作成、メイン処理、出力処理を分けた方が良いかなと)
3,については
CSVファイルの扱いは色々なやり方があります。
多分サンプルで、1行のみをコピぺしているようですが、
そのままExcelで開いて文字列、値など問題のないCSVファイルなのでしょうか?また、範囲は1行のみなのでしょうか?
取敢えず
更新日が3日以内のファイルを取得する方法(時間も関係するので仮要件)
No.1
- 回答日時:
こんにちは
ファイルをコピペする前に、日付でフィルターをかければよいだけのように思います。
>このファイル名から判別できるとよりありがたいです
>作成日時だと意図しないものもコピーされる恐れがある
とのことですが、ファイル名の規則がイマイチはっきりしないので・・・
「ファイル名の3~6文字目がmmdd形式の日付となっている」ものと仮定できる場合の一例を以下にあげておきます。
まず、事前に対象日を文字列として作成しておきます。
d1 = Format(Now(), "mmdd")
d2 = Format(Now() - 1, "mmdd")
d3 = Format(Now() - 2, "mmdd")
そのうえで、ループ内で
dd = Mid(Filename, 3, 4)
If dd = d1 Or dd = d2 Or dd = d3 Then
’ ここでファイルを開く処理
End If
のようにすることで、対象のファイルだけを処理できるようになるでしょう。
※ ファイル名の規則が違うような場合は、判定方法をそれに合わせて変えればよいです。
回答ありがとうございます。
日付でフィルターは、同作成日で10個ほどファイルがあり、それを隔週で行うためあまり効率的ではないと思いました。
ファイル名の規則は、4文字目からmmdd形式の日付となっています。
上記のコード追加して実行しましたが、延々ループとなってしまいました。
Sub test()
Const FolderPath As String = "C:TestFolder"
Dim FileName As String
Dim Sh0 As Range, Sh As Worksheet
Dim c As Long
Dim d1 As Date, d2 As Date, d3 As Date, dd As Date
d1 = Format(Now(), "mmdd")
d2 = Format(Now() - 1, "mmdd")
d3 = Format(Now() - 2, "mmdd")
Set Sh0 = ActiveSheet.Range("A2:Q2")
FileName = Dir(FolderPath & "\*.csv")
Do Until FileName = ""
c = c + 1
dd = Mid(FileName, 4, 4)
If dd = d1 Or dd = d2 Or dd = d3 Then
Set Sh = Workbooks.Open(FolderPath & "\" & FileName).Sheets(1)
Sh.Range("A1:Q1").Copy Sh0.Range("A" & c & ":Q" & c)
Application.DisplayAlerts = False
Sh.Parent.Close
Application.DisplayAlerts = True
FileName = Dir()
End If
Loop
End Sub
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) Excel VBAどこが間違ってますか? 4 2023/07/17 10:04
- Visual Basic(VBA) 複数csvを横に追加していくマクロについて 2 2023/04/25 09:19
- Visual Basic(VBA) VBAのユーザーフォームのテキストボックスに入力制限をしたい 6 2022/11/15 08:28
- Excel(エクセル) Excelにて、フォルダ内のTextファイルをマクロで統合すると文字化けしてしまう時の解消コード 4 2023/01/01 07:32
- Visual Basic(VBA) ExcelのVBAコードについて教えてください。 1 2023/08/09 10:33
- Visual Basic(VBA) エクセルのマクロについて教えてください。 1 2023/02/21 11:19
- Excel(エクセル) エクセルのVBAについて とあるサイトのコードを参考に、CSVの文字化けを直すVBAを作成しているの 7 2022/11/04 14:15
- Excel(エクセル) エクセルのマクロについて教えてください。 2 2023/02/21 13:29
- Visual Basic(VBA) フォルダの場所を可変にしたいです(マクロ) 4 2023/05/11 10:00
- Visual Basic(VBA) エクセルVBAについて 8 2022/07/13 22:41
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
0バイトのテキストファイル
-
【Excel VBA】取り込んだファイ...
-
MusicXMLファイル作り方教えて...
-
リソースファイルを認識してく...
-
Eclipseで検索ができなくなった
-
CSV名と同じシートを選択して取...
-
[C#]FTPでの複数のファイル...
-
ファイルの排他について
-
HTMLまたはJavaScriptでフ...
-
BASP21のファイルアップロード...
-
2GB以上のファイルを扱う方法
-
ACCESS97で作成したmdbファイル...
-
EXCELで複数のファイルを同じブ...
-
JavaでPDFファイルに変換するに...
-
C#について質問【複数の.datフ...
-
HTMLテキストリンクでExcelファ...
-
EUCコードをSHIFT-JISに変換したい
-
excel vba でファイルの読み込...
-
GetOpenFileName()について
-
VB6.0のメモリリークについて
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
【Excel VBA】取り込んだファイ...
-
0バイトのテキストファイル
-
VBAで、JPG写真の撮影日時を読...
-
HTMLテキストリンクでExcelファ...
-
Eclipseで検索ができなくなった
-
HTMLまたはJavaScriptでフ...
-
【VBA】複数CSVの特定範囲を1つ...
-
ディレクトリのサイズの取得
-
サイトマップにサブドメインを...
-
Javaのファイルダウンロードに...
-
リソースファイルを認識してく...
-
VBS ファイルマージ処理
-
C++.NET 2003 「空のドキュメ...
-
VB6.0のメモリリークについて
-
C++によるファイル送受信プログ...
-
RPGでメッセージファイル利用
-
Perlで2GBを超える大きいファイ...
-
VB6でTIFF図のプロパティを...
-
BASP21のファイルアップロード...
-
VB2008 iniファイルの全セクシ...
おすすめ情報
回答ありがとうございます。
日付でフィルターは、同作成日で10個ほどファイルがあり、それを隔週で行うためあまり効率的ではないと思いました。
ファイル名の規則は、4文字目からmmdd形式の日付となっています。
上記のコード追加して実行しましたが、延々ループとなってしまいました。
上記No1様への回答です。慣れてないもので補足に投稿いたしました。
下記追加補足です。
・同じ作成日が複数あり、(10個ほど)一つずつ開いてするのは非効率
・各csvファイルにはA1からQ1までで数値しか入っておりません。(通常の貼付けで対応可です。)
・貼り付け先(例:sheet仮)のA2からQ2に貼付け。張り付けられていたらA~Qのの最終行に貼付け。
拙い文ですがご査収ほど宜しくお願い致します。