🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

コピー

元のオブジェクトを破壊することなく、オブジェクトの複製を生成することをコピーと呼びます。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Q&A

解決済

2回答

1466閲覧

プログラムのエラー場所について

bonji

総合スコア37

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

コピー

元のオブジェクトを破壊することなく、オブジェクトの複製を生成することをコピーと呼びます。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

0グッド

0クリップ

投稿2019/11/16 03:49

編集2019/11/17 11:49

今、VBAで任意の範囲にあるデータをコピーする関数を作っています。
以下がそのプログラムです。

VBA

1Function コピー関数() 2Dim input_rg As Range 3Dim output_rg As Range 4Set input_rg = Application.InputBox("コピーするセルを選択してください", Title:="入力フォーム", Type:=8) 5Set output_rg = Application.InputBox("貼り付け先を選択してください", Title:="出力フォーム", Type:=8) 6 7If input_rg = False Or output_rg = False Then 8 End 9End If 10 11input_rg.Copy Destination:=output_rg 12 13 14End Function

これを実行すると、「型が一致しません」というエラーを吐き出します。
場所は[Set input_rg = Application.InputBox("コピーするセルを選択してください", Title:="入力フォーム", Type:=8)]の場所です。

このエラーメッセージを受けて
以下の様にしました。

VBA

11.イミディエイトウィンドウでセルのアドレスと型を調べました。 2?input_rg.address 3$C$3:$F$3 4?typename(input_rg) 5Range 6?typename(output_rg) 7Range 8?output_rg.address 9$C$10:$F$10 10 112.型をrange型からVariant形に変更しましたが、同じエラーを吐き出します。 12

回答の程、宜しくお願いします。

回答を受けて
まず、回答ありがとうございます。コメント欄に書こうか迷ったのですが、長文になりそうなのでこちらに書かせていただきます。

回答をいただいて、改めて実行した所、エラーを吐き出すことなく実行できました。
ただ、applicationinputboxのダイアログボックスでキャンセルを選択すると、再び[型が一致しません]というエラーを吐き出します。
調べたところ、inputboxのキャンセルの戻り値はFalseらしいです。
回答を頂いて恐縮ですが、この点を踏まえて、再度回答をしていただけると嬉しいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

imihito

2019/11/17 14:24

追記の部分はよくある話なので、検索すれば何かしら見つかったと思います。 最近のteratail内だと以下の質問とかですね。 inputboxメソッドでセルを指定させる際のキャンセル対策 https://teratail.com/questions/200242
bonji

2019/11/19 13:29

回答ありがとうございます。 紹介してくださったリンクに自分が知りたい情報が全て載っていました。 今度からは、こちらで調べてから質問させていただきます。
imihito

2019/11/19 22:36

解決したようで何よりです。 であれば、どなたかの回答をベストアンサーとして選んで、質問を「解決済み」にしてあげて下さい。
guest

回答2

0

ベストアンサー

エラー箇所ですが、本当にそこですか。当方でテストしてみたところ、そこはエラーなく通過しました。

が、

vba

1If input_rg = False Or output_rg = False Then 'ここでエラー 2 End 3End If

でエラーになりました。

オブジェクトの有無は、Is Nothing で判定します。
下記に修正したらエラーなく実行できました。

vba

1 If input_rg Is Nothing Or output_rg Is Nothing Then 2 Exit Function 3 End If

キャンセルに対応するコード

Function コピー関数() As Boolean Dim input_rg As Range Dim output_rg As Range コピー関数 = False On Error Resume Next Set input_rg = Application.InputBox("コピーするセルを選択してください", _ Title:="入力フォーム", Type:=8) If Err.Number <> 0 Then MsgBox "キャンセルされました。" Exit Function End If Set output_rg = Application.InputBox("貼り付け先を選択してください", _ Title:="出力フォーム", Type:=8) If Err.Number <> 0 Then MsgBox "キャンセルされました。" Exit Function End If If input_rg Is Nothing Or output_rg Is Nothing Then Exit Function End If input_rg.Copy Destination:=output_rg If Err.Number = 0 Then コピー関数 = True End If End Function

せっかく Function にしているので、コピーに成功したかどうかを返す仕様にしてみました。

おまけ

質問のコードではEndで関数を終了させようとしてますが、通常は、Exit Functionで関数から抜けるようにします。
ちがいは、End は実行中のマクロを完全に終了させますが、Exit Functionは関数から抜けた後、次のコードがあればそれは実行されます。違いを意識して使い分けるようにすべきでしょう。

参考コード

vba

1Sub hoge() 2 Debug.Print "hoge" 3 Exit Sub 4End Sub 5 6Sub fuga() 7 Debug.Print "fuga" 8 End 9End Sub 10 11Sub hogefuga() 12 Call hoge 13 Debug.Print "hageの次" 14 15 Call fuga 16 Debug.Print "fugaの次" 17End Sub

イミディエイトウィンドウ

hoge hageの次 fuga

投稿2019/11/16 04:09

編集2019/11/18 01:32
hatena19

総合スコア34073

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

bonji

2019/11/19 13:31

回答ありがとうございます。 Endの使い分けの仕方は知りませんでした。有益な情報ありがとうございます。 End functionに修正します!
guest

0

<再回答>
想定されるエラーでキャンセルを判定する方法を考えてみました。

VBA

1Function コピー関数() 2 Dim input_rg As Range, output_rg As Range 3 4 On Error GoTo myErr 5 Set input_rg = Application.InputBox("コピーするセルを選択してください", Title:="入力フォーム", Type:=8) 6 Set output_rg = Application.InputBox("貼り付け先を選択してください", Title:="出力フォーム", Type:=8) 7 On Error GoTo 0 8 9 'hatena19さんの回答 10 If input_rg Is Nothing Or output_rg Is Nothing Then 11 Exit Function 12 End If 13 input_rg.Copy Destination:=output_rg 14 15myErr: 16 If Err.Number = 424 Then 17 MsgBox "キャンセルされました。" 18 Err.Clear 19 Else 20 Err.Raise Err.Number 21 End If 22End Function

<以下回答は、キャンセルボタンでエラーとなり、解決できていませんでした。>
Inputboxのキャンセルの戻り値はFalseなので、Range型ではエラーとなります。
好みでないかもしれませんが、Variant型とすればキャンセルを判定する方法があります。

VBA

1Function コピー関数() 2'キャンセル判定のためにVariant型とする 3Dim input_vt As Variant, output_vt As Variant 4Set input_vt = Application.InputBox("コピーするセルを選択してください", Title:="入力フォーム", Type:=8) 5Set output_vt = Application.InputBox("貼り付け先を選択してください", Title:="出力フォーム", Type:=8) 6 7'キャンセルの判定 8If VarType(input_vt) = vbBoolean Or VarType(output_vt) = vbBoolean Then 9 Exit Function 10End If 11 12'hatena19さんの回答 13If input_vt Is Nothing Or output_vt Is Nothing Then 14 Exit Function 15End If 16 17input_vt.Copy Destination:=output_vt 18 19End Function

投稿2019/11/17 13:58

編集2019/11/18 09:57
TanakaHiroaki

総合スコア1063

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hatena19

2019/11/18 01:10

キャンセルで False が返った場合、Set しているところでエラーになりませんか。
TanakaHiroaki

2019/11/18 09:36

'hatena19さん、ご指摘ありがとうございます。 以下のエラーが出ました。  実行時エラー '13':  型が一致しません。 私なりに修正してみます。
bonji

2019/11/19 13:29

回答ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問