Excel (VBA)

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

 
(Windows 10 Pro : Excel 2016)
データの転記の際のエラーメッセージについて
投稿日時: 23/01/17 19:36:34
投稿者: マイルストン

お世話になっております。
現在、エクセルVBAのスキルアップを目指してネット等に掲載されているVBA関連の記事を見ながら勉強に励んでいます。下記のとおりコードを書いて実行したところ、「実行時エラー1004 アプリケーション定義またはオブジェクト定義のエラーです。」というエラーメッセージが表示されます。
どこが間違っているのか検討もつかない状況ですので、ご教示のほど宜しくお願いいたします。
 
Sub test()
 
    Dim lastrow As Long
        lastrow = Worksheets("一覧").Cells(Rows.Count, 1).End(xlUp).Row
    'ワークシート「一覧」に行番号を入力
    If Worksheets("一覧").Cells(lastrow, 1).Value = "番号" Then
        Worksheets("一覧").Cells(lastrow + 1, 1) = 1
    Else
        Worksheets("一覧").Cells(lastrow + 1, 1).Value = Worksheets("一覧").Cells(lastrow, 1).Value + 1
    End If
    '入力データをワークシート「一覧」に代入
    Worksheets("一覧").Cells(lastrow + 1, 2) = Worksheets("入力").Cells(1, 2)
    Worksheets("一覧").Cells(lastrow + 1, 3) = Worksheets("入力").Cells(2, 2)
    Worksheets("一覧").Cells(lastrow + 1, 4) = Worksheets("入力").Cells(3, 2)
    '代入後データの値をクリア
    Worksheets("入力").Range(Cells(1, 2), Cells(3, 2)).ClearContents
    'ワークシート「入力」の「セルB1」を選択
    Worksheets("入力").Cells(1, 2).Select
       
End Sub

回答
投稿日時: 23/01/17 20:17:12
投稿者: simple

>どこが間違っているのか検討もつかない状況です
エラー表示に「デバッグ」というボタンが表示されているはずです。
それをクリックすると、どの行でエラーになっているかが分かります。
 
かなりのFAQに相当する事象だろうとは想像します。
しかし、それよりも上記のとおり、
デバッグを開始するスタンスを確立するほうが重要だと思いますので、
まずは上記に沿って、第一歩を進めてください。
そして、必要な情報(エラー発生場所)を提示してください。

投稿日時: 23/01/17 21:26:12
投稿者: マイルストン

 simple 様
 
お世話になります。よろしくお願いいたします。
 
>エラー表示に「デバッグ」というボタンが表示されているはずです。
>それをクリックすると、どの行でエラーになっているかが分かります。
 
下記のコードの部分でエラー表示されます。
下記のコードをコメントブロックしたらエラーは表示されませんでした。
 
> Worksheets("入力").Range(Cells(1, 2), Cells(3, 2)).ClearContents

回答
投稿日時: 23/01/17 21:26:20
投稿者: WinArrow

陥りやすいコードの記述ミスだろうと思います。
 
特にセルをアクセスする場合、常に、そのセルが損じするシートを意識しないと、
このようン状況になります。
 

引用:
lastrow = Worksheets("一覧").Cells(Rows.Count, 1).End(xlUp).Row
    'ワークシート「一覧」に行番号を入力
    If Worksheets("一覧").Cells(lastrow, 1).Value = "番号" Then
        Worksheets("一覧").Cells(lastrow + 1, 1) = 1
    Else
        Worksheets("一覧").Cells(lastrow + 1, 1).Value = Worksheets("一覧").Cells(lastrow, 1).Value + 1
    End If

をシートを意識した記述に変更してみます。参考にしてくdさい。
    With Worksheets("一覧")
        lastrow = .Cells(.Rows.Count, 1).End(xlUp).Row
    'ワークシート「一覧」に行番号を入力
        If .Cells(lastrow, 1).Value = "番号" Then
            .Cells(lastrow + 1, 1) = 1
        Else
            With .Cells(lastrow, 1)
                .Offset(1).Value = .Value + 1
            End With
        End If
    End With

回答
投稿日時: 23/01/17 21:33:11
投稿者: WinArrow

> Worksheets("入力").Range(Cells(1, 2), Cells(3, 2)).ClearContents
----------------------@----A-----------B---------
 
@のRangeは、シートで修飾しているが、
ABのCellsは、シートで修飾していないから
ABは、実行時点でアクティブになっているシートを参照しています。
 
必ずエラーになるということでもなく、稀に動くときもある。

回答
投稿日時: 23/01/17 21:34:42
投稿者: WinArrow

語句訂正します
 
>そのセルが損じするシート

そのセルが存在するシート

回答
投稿日時: 23/01/17 22:04:41
投稿者: simple

回答を用意してありましたが、ついウトウトしてしまいました。
既に回答いただいたとおりです。
 
重複する点は触れません。若干の補足をします。
【エラーの原因】
test()が標準モジュールに書かれたものであれば
その時にアクティブなシートが省略されたものとみなされます。
もし、Worksheets("一覧")がアクティブなら、

Worksheets("入力").Range(Worksheets("一覧").Cells(1, 2), Worksheets("一覧").Cells(3, 2)).ClearContents
と指定したのと同じように解釈され、もちろん整合性がとれず、エラーとなります。
 
【備考】
ついでに言うと、test() がもしシートモジュールに書かれたプロシージャであれば
どのシートがアクティブであるかは関係なく、
そのシートモジュールに対応するシートを指定したものとみなされます。
 
ワークシート省略時に前提とされるシートは何か、についてよく理解されるとよいでしょう。

回答
投稿日時: 23/01/18 12:35:17
投稿者: simple

Worksheets("入力").Range(Worksheets("入力").Cells(1, 2), Worksheets("入力").Cells(3, 2)).ClearContents
と書く必要がありますが、これはいかにも冗長、見にくいので、With ステートメントを使って、
With Worksheets("入力")
    .Range(.Cells(1, 2), .Cells(3, 2)).ClearContents
End With 
と書くのが一般的です。
 
その他、
    Worksheets("入力").Cells(1, 2).Resize(3).ClearContents
と書いても同じ効果があります。

投稿日時: 23/01/18 21:14:10
投稿者: マイルストン

WinArrow 様
 
>シートを意識した記述に変更してみます。参考にしてくdさい。
 
ありがとうございます!
大変勉強になります。シートを意識した記述に気を付けるためには
具体的には、どのようなことに気を付けていけばよろしいでしょうか。
ご教示のほど宜しくお願いいたします。
 
simple 様
 
>With Worksheets("入力")
> .Range(.Cells(1, 2), .Cells(3, 2)).ClearContents
>End With
 
上記のように記述しても同様のエラーがでました。
私なりに調べてみたところ、入力シートがアクティブセルがある場合は
エラーが表示されず、一覧シートにアクティブセルがある場合には
エラーが表示されるようです。
 
それで、次のように記述したら一覧シートにアクティブセルがある場合にマクロを
実行してもエラーは表示されませんでした。
 
Worksheets("入力").Activate
>With Worksheets("入力")
> .Range(.Cells(1, 2), .Cells(3, 2)).ClearContents
>End With
 
上記のような記述でも問題ないというか、もっと、適切な記述の仕方が
あったりするのでしょうか。
ご教示のほど宜しくお願いいたします。
 

回答
投稿日時: 23/01/18 21:21:38
投稿者: simple

>上記のように記述しても同様のエラーがでました。
 
そうですか、おかしいですね。
恐縮ですが、実行したコードを、VBE(コードの編集画面)から直接コピーペイストして、
(つまり、手打ちして投稿せずにということです)こちらに提示してもらえますか?
前と同じく、Sub から End Subまで全体を示してください。

回答
投稿日時: 23/01/18 21:26:59
投稿者: simple

併せて、どの行でエラーになって、なんというエラーメッセージが出ますか?
# 大体の想像はつきますが、念のため。

投稿日時: 23/01/18 21:34:34
投稿者: マイルストン

simple 様
 
コードは下記のように記述しています。
 
 
Sub test()
 
    Dim lastrow As Long
        lastrow = Worksheets("一覧").Cells(Rows.Count, 1).End(xlUp).Row
    'ワークシート「一覧」に行番号を入力
        With Worksheets("一覧")
        lastrow = .Cells(.Rows.Count, 1).End(xlUp).Row
    'ワークシート「一覧」に行番号を入力
        If .Cells(lastrow, 1).Value = "番号" Then
           .Cells(lastrow + 1, 1) = 1
        Else
            With .Cells(lastrow, 1)
                 .Offset(1, 0).Value = .Value + 1
            End With
        End If
    End With
    '入力データをワークシート「一覧」に代入
    Worksheets("一覧").Cells(lastrow + 1, 2) = Worksheets("入力").Cells(1, 2)
    Worksheets("一覧").Cells(lastrow + 1, 3) = Worksheets("入力").Cells(2, 2)
    Worksheets("一覧").Cells(lastrow + 1, 4) = Worksheets("入力").Cells(3, 2)
    '代入後データの値をクリア
    With Worksheets("入力")
        .Range(.Cells(1, 2), .Cells(3, 2)).ClearContents
    End With
    'ワークシート「入力」の「セルB1」を選択
    Worksheets("入力").Cells(1, 2).Select
     
End Sub
 
 
エラーメッセージは、
 
> Worksheets("入力").Cells(1, 2).Select
 
上記の行の処理が終了した後に出ます。
内容は、「実行時エラー1004 アプリケーション定義またはオブジェクト定義のエラーです。」というエラーメッセージが表示されます。
 
よろしくお願いいたします。
 
 

回答
投稿日時: 23/01/18 21:45:43
投稿者: simple

# また別の箇所のエラーですよね。想定していました。
# エラー箇所の特定は質問時に書いて下さいね。(2度目)
 

Worksheets("入力").Cells(1, 2).Select
は Worksheets("入力")がアクティブでないとエラーになります。そういう仕様です。
そのシートをアクティブにしてから、セルを選択してください。
 
もしくは、
    Application.Goto Worksheets("入力").Cells(1, 2)
とするかです。(この場合、シートをアクティブにしなくてもOKです。)
混乱するようでしたら、後者の話は無視して下さい。

投稿日時: 23/01/19 19:00:14
投稿者: マイルストン

simple 様
 
お世話になっております。
色々とご教示いただきありがとうございます。
 
> Worksheets("入力").Cells(1, 2).Select
> は Worksheets("入力")がアクティブでないとエラーになります。そういう仕様です。
> そのシートをアクティブにしてから、セルを選択してください。
 
なるほど。。。不勉強でお恥ずかしい限りです。日々精進したいと思います。