質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.50%
VBA

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

Q&A

解決済

1回答

8424閲覧

【VBA】Excelファイルを開いた際のエラーに関して

ymchs795

総合スコア13

VBA

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

0グッド

1クリップ

投稿2017/06/07 08:15

###前提・実現したいこと
お世話になります。
初めてこちらを利用させていただきます。
前任者が作成したVBAでエラーが発生する旨の報告を受けました。
エラーを解消したいのですが、当方Java,VB.netを少々かじっていた程度で、VBAに至ってはほぼ初見で理解できずにおります。

###発生している問題・エラーメッセージ
現象と致しましては、Excelファイルを開いた際に初回はエラーが出ないのですが、一度閉じて再度開くと下記のエラーが表示されます。
①Windows7 32bit/Excel2013 32bitの場合:「次の非表示モジュール内でコンパイルエラーが発生しました:メイン処理」
②Windows7 32bit/Excel2010 32bitの場合:「実行時エラー'1004' 'CutCopyMode'メソッドは失敗しました。'_Application'オブジェクト」
③Windows10 32bit/Excel2016 32bitの場合:ファイルをダブルクリック後、EXCELの起動ロゴまでは出るが立ち上がらない。
このように、Windows,Excelのバージョンでエラーの内容が異なります。

###該当のソースコード
Dim データ範囲 As Range
Dim データセル As Range
Dim 転記先範囲 As Range
Dim 転記先セル As Range
Dim データ件数 As Integer

Sub メイン()
Application.ScreenUpdating = False
Worksheets("売上報告書").Unprotect PASSword:=""
Range("B4:N340").Copy Range("B4:N340")
並べ替え
品名コード抽出
集計
Worksheets("売上報告書").Protect PASSword:=""
Application.ScreenUpdating = True
End Sub

Sub 並べ替え()
With ThisWorkbook.Worksheets("売上報告書")
.Range("B4").CurrentRegion.Sort Key1:=Range("B5"), Key2:=Range("D5") _
, Header:=xlYes, MatchCase:=False, Orientation:=xlTopToBottom, SortMethod:=xlPinYin
.Range("B5").Select
End With
End Sub

Sub 品名コード抽出()
With ThisWorkbook.Worksheets("品名マスタ")
.Unprotect PASSword:=""
With .Range("B1").CurrentRegion
Set データ範囲 = .Offset(2).Resize(.Rows.Count - 1, 1)
End With
.Protect PASSword:=""
End With

With ThisWorkbook.Worksheets("売上報告書").Range("F4").CurrentRegion Set 転記先範囲 = .Offset(1, 4).Resize(.Rows.Count - 1, 1) End With For Each 転記先セル In 転記先範囲.Cells For Each データセル In データ範囲.Cells If 転記先セル.Value = データセル.Value Then Select Case 転記先セル.Offset(, 1).Value Case 1 To 115 転記先セル.Offset(, -1) = データセル.Offset(, 1) Case 116 To 254 転記先セル.Offset(, -1) = データセル.Offset(, 2) Case Else 転記先セル.Offset(, -1) = データセル.Offset(, 3) End Select Exit For End If Next データセル Next 転記先セル Application.CutCopyMode = False

End Sub

Sub 集計()
データ件数 = WorksheetFunction.CountIf(Worksheets("売上報告書").Range("M5:M340"), "<>0")
If データ件数 > 0 Then
With ThisWorkbook.Worksheets("売上報告書").Range("B4")
.Resize(1 + データ件数, 13).Subtotal GroupBy:=2, Function:=xlSum, TotalList:=Array(10, 12), _
Replace:=True, SummaryBelowData:=True
.Activate
End With
Else
MsgBox Prompt:="データがありませんよ!", Buttons:=vbExclamation, Title:="注意"
End If
End Sub

Sub 集計解除()
With ThisWorkbook.Worksheets("売上報告書")
.Unprotect PASSword:=""
.Range("B4").RemoveSubtotal
.Protect PASSword:=""
End With
End Sub

Sub 印刷()
Application.ScreenUpdating = False
データ件数 = WorksheetFunction.CountIf(Worksheets("売上報告書").Range("M5:M340"), "<>0")
Worksheets("売上報告書").PrintOut To:=WorksheetFunction.RoundUp(データ件数 / 28, 0)
Application.ScreenUpdating = True
End Sub

Sub データクリア()
Application.ScreenUpdating = False
集計解除
With ThisWorkbook.Worksheets("売上報告書")
.Unprotect PASSword:=""
.Range("B5:B340,D5:L340,N5:N340").ClearContents
.Range("B5").Select
.Protect PASSword:=""
End With
Application.ScreenUpdating = True
End Sub

###試したこと
デバッグで動かしてもエラーが発生しなかったため、不要そうな部分をコメントアウトしてファイルを再度開くということを繰り返していると、1行目~4行目Range型の変数宣言でこけているということがわかりました。
Range型ではなくObject型で宣言すればエラーが発生せず正常にファイルを開くことができるのですが、なぜ動くようになったのか不明なうえ、この対処方法で良いものなのか、また問題②の'CutCopyMode'メソッドの件は放置してよいのか、といった疑問が残ります。
③の問題に関しては、エラーが表示されなくなったことでファイルを正常に開くことができるようになりました。

###補足情報(言語/FW/ツール等のバージョンなど)
長文となってしまい申し訳ございませんが、どなかご回答をよろしくお願い致します。

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

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

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

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

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

guest

回答1

0

ベストアンサー

型をObjectにすれば動作するとのことなので、アーリーバインディングに伴って発生している問題なのだと推測しています

VBAはComponent Object Model(以下COM)に強く依存した開発言語です。メソッドを呼び出すときの名前解決などを実行時に行う方法がレイトバインディング、コンパイル時などに行う方法がアーリーバインディングです。VBAでは型をRange等のように明示した場合はアーリーバインディング、Object型として宣言した場合がレイトバインディングにあたります。

アーリーバインディングにしておけばコンパイル時にエラーとなったり、メソッド入力時に名前の補間処理などが動いて便利なので、アーリーバインディングでコードを書くことが多いです。ですがアーリーバインディングには欠点があり、様々なバージョンのExcel上で動作を保証することが困難になります。Excelのバージョンによって引数が変わっていたり、メソッドがなかったりすると、エラーとなってしまうからです。

従って様々なバージョンのExcelで動作させたいのであれば、Object型で宣言し、レイトバインディングを用いた方が無難です。「実行環境を特定のバージョンに固定できないなら、レイトバインディングを採用すべし」というのは、VBAやVB6.0が全盛だった15年位前にはよく知られていたバッドノウハウです。

もう一つの可能性として、VBAの参照設定を確認してみて下さい。Excel2010の環境で新規に作成したExcelファイルの参照設定と同じ状態にすれば動くかも知れません。

投稿2017/06/08 01:39

Kunihiro_Narita

総合スコア472

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

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

ymchs795

2017/06/08 05:02

丁寧なご回答、ありがとうございます。 Object型を使う方法で問題なさそうであるため、そのように対処したのですが、 原因を調査していた私のPC(Win7 32bit/Excel2013 32bit)では正常に動きましたが、質問欄にある①、②のPCにおいて、②のエラーメッセージが表示されてしまいます。 こちらの対処方法などございましたらご教示いただけますでしょうか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問