- ベストアンサー
VBAで複数パラメータの自動処理方法を学ぶ
- VBAコード内で複数のパラメータをリストアップし、順番に処理する方法について詳しく説明します。この方法を活用すれば、作業を自動化することができます。
- 示されたVBAコードは複数の検索文字列(SearchStr)を配列に格納し、これを順次呼び出して自動で処理する方法を提案しています。コードの改良案や別案についてのアドバイスも求められています。
- 実際の便用は想定していない「卓上の案」として、事前に複数リストアップしたパラメータを順次処理するVBAの方法論について解説。改良案や他の提案も募集しています。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
配列を渡さずに質問のコードのようにstrを渡せばいいのではないでしょうか
その他の回答 (3)
- kkkkkm
- ベストアンサー率66% (1719/2589)
> str=Serchstrは、配列なのでSerchstrをそのまま渡せないのでは無いでしょうか? この意味がよく分かりません。 Serchstrをそのまま渡せないのに(渡せるけど受け取る側でそのように設定していない) Call call1(FPath, Serchstr) になってました。 For EachでRangeなどのようなオブジェクトの塊をループした場合 オブジェクト変数にひとつずつオブジェクトとして渡されますが 配列の場合は、配列の要素がひとつずつ渡されます。 配列に関して参考にしてください。 【VBA】配列の要素を全て取り出せる!For Each〜Next文の使用方法【5分で理解】 https://goodtmrow.com/vba-repet-foreach-begginer/ なので For Each str In SearchStr Call call1(FPath, str) Next str でしたらFor Eachの部分で For i=xx ~NextのStr = SearchStr(i) と同じ事が行われているという感じです。 あと、プロシージャーの引数のByValとByRefを付けていませんが付けるようにした方がいいと思います。 省略すると「ByRef」となり、呼び出し先で値を変更すると元の値も変更されてしまいます。 配列などByRefでないと渡せないものもあります。
お礼
>呼び出し先で値を変更すると元の値も変更されてしまいます。 ありがとうございます。 質問者からの補足(2023/07/26 12:38)のように サブルーチン側で引く数が書き換わる可能性があるコードは利用していませんが 念には念でByValで固定すべく Sub RenameFilesInFolder(ByVal folderPath As String, ByVal searchStr As Variant) に変更しました。
- kkkkkm
- ベストアンサー率66% (1719/2589)
Sub call1(FPPath As String, searchStr As Variant) じゃないと Call call1 (FPath, searchStr) のところでエラーになりませんでしょうか。 あと Call call1 (FPath, searchStr) でしょうか? 元が For Each str In SearchStr Call call1(FPath, str) Next str でした。
補足
すいません。 コードを全て開示しないとアドバイスが付けにくいと思うので 以下に現在の旧コードを記載します。 この旧コードを元に パラメターのSearchStrを事前に複数リストアップして 順番に一つずつ読み込ませて自動で処理させるコードに改良したいと思っています。 Sub main() Dim searchStr As String Dim folderPath As String searchStr = InputBox("ファイル名から削除する文字列を入力して下さい。", "削除文字列_指定") If searchStr = "" Then MsgBox "Cancelが入力されました。" Exit Sub End If folderPath = InputBox("検索するドライブを入力して下さい。", "ドライブレター_指定", "E:\") If folderPath = "" Then MsgBox "Cancelが入力されました。" Exit Sub End If RenameFilesInFolder folderPath, searchStr MsgBox "ファイル名の変更済み。" End Sub Sub RenameFilesInFolder(folderPath As String, searchStr As String) 'Dim folderPath As String 'Dim searchStr As String Dim file As Object Dim files As Object Dim fPath As Object ' フォルダーパスと検索文字列を指定 'folderPath = "E:" 'searchStr = "[DELETE]" '仮のサンプル ' フォルダー内の全てのファイルを取得 Set files = CreateObject("Scripting.FileSystemObject").GetFolder(folderPath).files Set fPath = CreateObject("Scripting.FileSystemObject").GetFolder(folderPath) If (Not fPath.isRootFolder) And (fPath.Attributes And (FileAttribute.System + FileAttribute.Hidden)) Then Exit Sub ' ファイル名を変更(同名ファイルが存在する場合は()付きの番号を付加する) For Each file In files If InStr(file.Name, searchStr) > 0 Then Dim NewName As String Dim i As Integer i = 1 NewName = Replace(file.Name, searchStr, "") Do While Dir(file.ParentFolder & "\" & NewName) <> "" NewName = Replace(file.Name, searchStr, "") & "(" & i & ")" i = i + 1 Loop file.Name = NewName End If Next file For Each file In fPath.subFolders RenameFilesInFolder file.Path, searchStr Next End Sub
- kkkkkm
- ベストアンサー率66% (1719/2589)
リストをコードの中で設定するのでしたら、通常そのような展開になると思いますから悪くないと思います。
お礼
kkkkkmさん、毎回お世話になっています。 今回もアドバイス感謝します。 改良前の以下のコードでは、 SeathStrは、inputboxで手動入力で一つだけを指定していたので SearcStrは、Dim serchStr as StringとString型で定義していました。 Sub main() Dim serchStr as String call1 FPath,SearchStr end sub Sub call1(FPPath As String, searchStr As String) ’---------------------------------------------------------- SearchStrを複数使用するので改良版では Dim SearchStr As VariantとVariant型で定義に変更していますが、 Call call1 (FPath, searchStr) (又は call call1 FPath,serachStr) Call先のcall1内の以下のコード If InStr(file.Name, searchStr) > 0 Then において 実行エラー:型が一致しません となります。 searchStrをArrayで3個指定しているので searchStr(0),searchStr(1),searchStr(2)となりますが 配列変数なので If InStr(file.Name, searchStr) > 0 Then のコードではダメなのでどのように書き換えたら良いでしょうか ?
お礼
最初の質問時のコードでミス記載していますが Call call1(FPath, str) は、 Call call1(FPath, Serchstr) です。 旧コードでは、 RenameFilesInFolder folderPath, searchStr です。 >配列を渡さずに質問のコードのようにstrを渡せばいいのではないでしょうか この意味が良くわからないのですが。 str=Serchstrは、配列なのでSerchstrをそのまま渡せないのでは無いでしょうか? 考え方が間違っていますか ?
補足
頭を冷やして考えなおしました。 配列変数ではなく普通の変数にして引き継げば良いのですね。 以下で一応処理できているようですが アドバイス有ればお願いします。 Sub main() Dim searchStr As Variant Dim folderPath As String Dim searchList As Variant Dim i As Long searchList = Array("[DELETE]", "[delete]", "【Delete】") ' 検索文字列のサンプルリスト folderPath = InputBox("検索するドライブを入力して下さい。", "ドライブレター_指定", "E:\") If folderPath = "" Then MsgBox "Cancelが入力されました。" Exit Sub End If For i = LBound(searchList) To UBound(searchList) searchStr = searchList(i) RenameFilesInFolder folderPath, searchStr Next i MsgBox "ファイル名の変更済み。" End Sub Sub RenameFilesInFolder(folderPath As String, searchStr As Variant)