Excel (VBA)

Excel VBAに関するフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(Windows 10全般 : Excel 2016)
アプリケーション定義またはオブジェクト定義のエラーについて
投稿日時: 21/05/28 20:55:41
投稿者: 初心者の卵

下記のようなVBAがなぜかうまく実行できません。
エラー内容、アプリケーション定義またはオブジェクト定義のエラー
 
転記マクロ1には異常がないことは確認済みです。
どこをどのように修正すればよろしいでしょうか。
 
 
 
Sub 転記マクロ_Main()
 
 Const FIND_STR = "検索文字A" ' 検索する文字列
 
 Const Hin = "検索文字B" ' 検索する文字列
 
 Const 検索文字$ = "ここからコピー"
 
 Dim sh As Worksheet, myFileName As String
 
 Dim shs As Worksheet, sh2 As Worksheet
 
 Dim i As Integer
 
 Dim h As Integer
 
 Dim wb As Workbook
 
  
 
 myFileName = Dir(ThisWorkbook.path & "\*" & "シート" & "*.xls?", vbNormal)
 
 Set shs = ThisWorkbook.Sheets("実績")
 
 
 
 i = 6
 
 h = 6
 
  
 
 Do Until myFileName = ""
 
 If InStr(myFileName, "シート") > 0 Then
 
 Set wb = Workbooks.Open(myFileName)
 
 If sh.Name Like "*" & FIND_STR & "*" Then
 
 For Each sh2 In wb.Worksheets
 
 Call 転記マクロ1(i, sh2, sh, 検索文字$)
 
 i = i + 1
 
 Next sh2
 
 wb.Close
 
 End If
 
 End If
 
 myFileName = Dir()
 
 Loop
 
End Sub
 
〜〜〜〜〜〜
 
Sub 転記マクロ1(i As Integer, shs As Worksheet, wsLookIn As Worksheet, 検索文字 As String)
 
 
 
以下の処理は、文字数の制限上省略
 
簡単に言うと、コピーして、ペーストしてます。
 
〜〜〜〜〜〜〜〜

回答
投稿日時: 21/05/28 22:12:20
投稿者: WinArrow
投稿者のウェブサイトに移動

まず、インデントをきちんとつけることです。
そうすると、マクロの構造が見えてきます。
  
以下は、あなたが掲示したコードにインデントを付けた例です。
1行おきに記述するから、見えにくくなる。
    

    myFileName = Dir(ThisWorkbook.Path & "\*" & "シート" & "*.xls?", vbNormal)
    
    Set shs = ThisWorkbook.Sheets("実績")
    i = 6
    h = 6
    
    Do Until myFileName = ""
        If InStr(myFileName, "シート") > 0 Then
            Set wb = Workbooks.Open(myFileName)
            If sh.Name Like "*" & FIND_STR & "*" Then
                For Each sh2 In wb.Worksheets
                    Call 転記マクロ1(i, sh2, sh, 検索文字$)
                    i = i + 1
                Next sh2
                wb.Close
            End If
        End If
        myFileName = Dir()
    Loop

  
ここで、問題は、
wb.Close
と位置です。
  
下の行の「End If」と逆になっていることが分かります。
自分で検証してみましょう。
  

回答
投稿日時: 21/05/28 22:20:31
投稿者: simple

>エラー内容、アプリケーション定義またはオブジェクト定義のエラー
そのエラーはどの行で発生しますか?
その時、関係する変数に異常はみられませんか?
確認して回答願います。

回答
投稿日時: 21/05/29 10:17:34
投稿者: simple

質問者さんからすると、
わからないから質問しているんですよ、ということかもしれません。
質問に対して質問で返すとは、と思っているのかもしれません。
 
こうした質問もよく拝見しますが、
ご自分でできるところまでは是非ご自分でトライして欲しいのです。
それが、今後のコード作成にも役立ってくるのです。
 
こうした「デバッグ」(コードの誤りを修正する作業)というものは、
コードを作成する作業に伴って、必ずと言っていいほど付随して発生するもので、
普通のことなんです、誰でもそうです。
その対応方法を是非マスターしていてだきたいですね。
 
そのための第1ステップは、事象をよく観察することです。
・エラーが発生すると、エラーメッセージが表示され、
  そこに"デバッグ"ボタンが表示されているはずです。
・それをクリックすると、黄色くハイライトされた行が表示されます。
・そして、その時、ローカルウインドウには、各種の変数のプロパティが表示されるはず。
 そこをよく見て欲しいわけです。
 
もちろんコードを見ていってもおかしいところは判別します。
しかし、長いものになると、自分では気づかない原因があることも多いです。
是非、ご自分でそのデバッグの一端を経験して頂きたいわけです。
 
なお、このほかの各種のデバッグ手法も書籍には書いてあるはずですので、
ステップを踏んで学習しておかれると良いでしょう。
(また、エラーが出ない場合でも、ステップ実行して(F8キーを押すことで実現)みると、
ワンステップ毎にどのような処理が行われるかを確認することができます。
これはコードを理解するための有効な方法なので、是非実行してみられるとよいと思います。)
 
==========
参考までに、コードを拝見しての気づきを以下に書きます。
(1)
If sh.Name Like "*" & FIND_STR & "*" Then
のshは、変数宣言されているものの、実際の割当がされていないのでエラーになるはずです。
(質問にあるエラーメッセージと微妙に違うので、別のエラーが先に発生しているのかもしれません。
実際に動作させているコードと字義通り同一であることは保証されないので、何とも言えませんが。)
 
(2)
また、コードの意図としては、
For Each sh2 In wb.Worksheetsで見ていく、各シートのシート名を調べたい、
と推察されるので、そのコード片を置く場所も違い、
sh2.Nameを調べるのではないですか?この辺は考え方を整理する必要があります。
 
(3)
これはエラーと関係はありませんが、
If InStr(myFileName, "シート") > 0 Then は、
もともと"シート"が含まれるブックをDirで取得しているわけだから、
含まれるのは当然で、余り意味がないかもしれませんね。
念のための検証ということですか?
 
(4)Closeの位置については、既にご指摘のありましたとおりです。
 
まだ経験が浅いためと思われますが、指摘頂いたインデントはかなり重要な話です。
コードを書くにもデバッグにも、かなりその効率に影響してきます。
逆にいうと、今の方法は相当なハンディキャップを背負って登山しているようなものです。
是非、正しいインデントをつけられたらよいと思います。
一行空けも意味が乏しいです。緊張感の無い漫然とした文章と同じ感じになりがちです。

回答
投稿日時: 21/05/29 15:26:12
投稿者: WinArrow
投稿者のウェブサイトに移動

simpleさんから、手厳しい、且つ、あったかいコメントりましたが、
私は、インデントを正しくないと、読む気がしません。
そのため、コードの内容まで見ていませんでした。
  
おかしなところ、2ヶ所を見つけました。

引用:
If InStr(myFileName, "シート") > 0 Then '@
Set wb = Workbooks.Open(myFileName) ’A
If sh.Name Like "*" & FIND_STR & "*" Then 'B

  
@このコードは、なくてもよいと思います。
   Dir関数で「*シート* 」を指定しているので、敢えて、再確認は不要と思います。
  あっても害にはならないから、問題ではない。
Aこのコードは、重大な問題です。
 WorkBooks.Openの引数には、フルパスのファイル名が必要です。
しかし、ここで指定しているのは、フォルダ名抜きのファイル名です。、
当然、エラーになります。
Bこのコードは、このままだと、A解決後、エラーになると思われるコードです。
(a)shの実態がない。
(b)もしかしたら、「sh2」 かも?・・・とすると、記述場所が間違っている。
 
 
注意
エラーになったときは、どこで(コードの場所)を示すこと。必須です。
この説明を省くと、回答は貰えないと考えてください。
  

回答
投稿日時: 21/05/29 19:13:29
投稿者: WinArrow
投稿者のウェブサイトに移動

一部誤解があるといけないので、補足します。
 
> WorkBooks.Openの引数には、フルパスのファイル名が必要です。
フルパスのファイル名とは、フォルダ名+ファイル名ということです。
フォルダ名を省略することもできますが、
その場合、カレントフォルダを指定したと解釈し、カレントフォルダにはいいているファイルを探します。
今回の場合、カレントフォルダ以外のファイルなので、フルパスで指定する必要があります。
 

投稿日時: 21/05/31 20:34:44
投稿者: 初心者の卵

WinArrow さんの引用:
一部誤解があるといけないので、補足します。
 
> WorkBooks.Openの引数には、フルパスのファイル名が必要です。
フルパスのファイル名とは、フォルダ名+ファイル名ということです。
フォルダ名を省略することもできますが、
その場合、カレントフォルダを指定したと解釈し、カレントフォルダにはいいているファイルを探します。
今回の場合、カレントフォルダ以外のファイルなので、フルパスで指定する必要があります。