【アプリ版】サポートOS変更のお知らせ

Excel2013VBAでたまに、ユーザー定義型は定義されていません、というエラーが発生しています。
症状からは、コード自体の問題ではない気はしますが、参照設定のライブラリファイルのチェックが不足しているのか、よく分かりません。
発生しているシートに記載しているコードを上げておきます。

Private Sub Worksheet_Change(ByVal Target As Excel.Range)
Dim ws As Worksheet
Set ws = ThisWorkbook.ActiveSheet
On Error Resume Next
If Intersect(Target, Range(ws.Cells(Target.Row, 2), ws.Cells(Target.Row, 3))) Is Nothing Then
Exit Sub
Else
Call ABCD
End If
End Sub

このコードはシート内のセルが変更された時に動作するイベントマクロで、エラーの発生が、ほぼ確実に起きると思われるやり方は、このコード全体を、まずコメントブロックし、次に非コメントブロックで動作可能状態に戻し、該当シートのセルに文字を入力すると、ユーザー定義型は定義されていません、というエラーが1回はほぼ必ず発生しています。エラーがでても、そのままOKを押すと、コード自体は問題なく実行処理される。次、またそのままセルに文字を入力してもエラーは発生しない。もしかすると何かのタイミングで発生するかもしれない。
その後、またコメントブロックする。そして、セルに文字を入力すると、なぜかここでも1度、同じエラーが発生する。その後は、出ない。
というよく分からない症状が出ています。
参照可能なライブラリ ファイルのチェックは、現在、

Visual Basic For Applications
Microsoft Excel 15.0 Object Library
OLE Automation
Microsoft Office 15.0 Object Library
Microsoft Forms 2.0 Object Library
Microsoft VBScript Regular Expressions 5.5

にチェックを入れています。
他、
Microsoft Active Data Objects 6.1 Library
Microsoft Scripting Runtime
上記2つをそれぞれチェックを入れましたが、変化なしです。

ちなみみに、同じシートに、下記のようなコードも記載していますがこちらは発生状況からすると除外できるのかな、と考えています。
Private Sub Worksheet_Deactivate()
On Error Resume Next
If あいう.Visible = True Then Unload あいう
End Sub

その他、標準モジュールや別のシートにも他のコードが記載されていますが、発生状況からこちらもとりあえず除外してもよいのかな、と考えています。
このような状況なのですが、何かエラーの原因になりそうな所があるでしょうか?
よろしくお願いいたします。

質問者からの補足コメント

  • これは、標準モジュールに記載しています。
    これ単独での動作に問題はありません。

    No.1の回答に寄せられた補足コメントです。 補足日時:2019/01/06 04:21
  • Option Explicit
    で、宣言しないと必ずエラーが出るようにしています。
    だいたいは、普通に動作しています。
    何かのタイミングで、エラーが出るようです。
    最初に示したコードを記載していない他のシートでも、セルの値を削除したタイミングで同じエラーが発生したので、最初に示したコードは関係ないと思われました。
    もう一つのコードの影響なのかもしれません。下に示したコードは、今回エラーが出た別のシートにも記載してあったので。
    Private Sub Worksheet_Deactivate()
    On Error Resume Next
    If あいう.Visible = True Then Unload あいう
    End Sub
    ただこちらも同様に、コメントアウトしてセルに文字を入力すると同じエラーがでました。(この頁のイベントマクロは何もない状態)意味不明。他の頁記載のこのイベントが悪さ?

    No.2の回答に寄せられた補足コメントです。 補足日時:2019/01/06 13:19
  • とりあえず、アドバイスに従い切り分けの為全てのシートのイベントをコメントブロックしました。
    そして、質問にだしたシートのPrivate Sub Worksheet_Change(ByVal Target As Excel.Range)のみ残し、On Error Resume Nextも削除した状態で試しました。
    ブックに一つだけイベントを残した状態で、その残したイベントを一旦全てコメントブロックしました。これで、このブックにイベントで動作するものは一つもない状態になりました。
    そこで、該当のシートに文字を入力すると、やはり同様のエラーが発生しました。プログラムは何も自動で実行するものはありません。これを見る限りシートは関係なさそうなので、コメントブロックすると他のシートでも同様の症状です。エラーの場所は、示されません。フォームが悪さをしている可能性も疑いこちらも全てブロックしています。

    No.3の回答に寄せられた補足コメントです。 補足日時:2019/01/06 13:38
  • そのチェックは、外部のデータアクセス機能に関するもののようなので自分のファイルには不要なものだと思います。
    一応変化しないことは確認済です。

    No.4の回答に寄せられた補足コメントです。 補足日時:2019/01/06 14:46
  • 補足ありがとうございます。
    コードは、提示のものと差し替えてみました。動作的には、変化はありません。エラーの状況も同じです。
    コンパイルでエラーはありませんでした。
    参照設定は、外せるものは外して再設定しました。
    Visual Basic For Applications
    Microsoft Excel 15.0 Object Library
    Microsoft Forms 2.0 Object Library
    上記については、使用中のコントロールまたは参照を削除することはできません。と表示されたので、再設定できませんでした。
    Microsoft Active Data Objects 6.1 Library
    は、チェックを外して、
    Microsoft Active Data Objects 2.8 Library
    に変更しました。

    No.5の回答に寄せられた補足コメントです。 補足日時:2019/01/07 23:13
  • 100%かどうかは確信はないですが、分かってきたのが、シートモジュールを変更した後、セルに値を入力すると、ユーザー定義型は定義されていません、というエラーが1度だけ発生するような気がします。その後エラーは、シートモジュールを変更しないと発生しない気がします。
    よってシートモジュールに記載しているコード全てにコメントブロックをかけて、動作するコードがなくなっても変更とみなしエラーが1度は発生するようです。
    そのことから、コードの内容ではなく、このExcelファイルの何かが壊れているのかな?という感じはしています。
    最悪は、新規に作り変えれば直るのかな、とも考えていますが、結構色々作りこまれており、新規ファイル移行は手間がかかる為、これを直して使えればいいとは思っています。

      補足日時:2019/01/07 23:26
  • フォームと列を非表示にするマクロを削除したらエラーがでなくなる様な気がします。
    フォームのマクロはまだ作成途中なので内容検証は難しいですが、(一応立ち上がりは問題なし、エラーもなし状態)、列非表示のマクロは何か変な所があるでしょうか?エラーは無。dicは他モジュールでも使用有。
    とりあえず文字制限で分割です。
    Public Sub 指定列非表示()
    Dim mydic As Object
    Dim ws As Worksheet
    Dim last_row As Long
    Dim c As Range
    Set mydic = Nothing
    Set mydic = CreateObject("Scripting.dictionary")
    Set ws = ThisWorkbook.ActiveSheet
    last_row = ws.Range("BM2").End(xlDown).Row

    No.6の回答に寄せられた補足コメントです。 補足日時:2019/01/13 17:07
  • 続き。
    For Each c In ws.Range(ws.Cells(2, 65), ws.Cells(last_row, 65))
    If Not mydic.Exists(c.Value) Then
    mydic.Add c.Value, Trim(c.Offset(, 1).Value)
    End If
    Next c
    For Each c In ws.Range(ws.Cells(6, 3), ws.Cells(6, 59))
    If mydic.Exists(c.Value) Then
    If mydic.Item(c.Value) = "×" Then
    c.EntireColumn.Hidden = True
    Else
    c.EntireColumn.Hidden = False
    End If
    End If
    Next c
    Set mydic = Nothing
    End Sub

      補足日時:2019/01/13 17:09
  • 内容のご確認ありがとうございます。
    結合セルも特になく、このコードの使用自体は問題はありません。動作も思い通りでエラーになるような事もありません。
    後は、フォームの方ですが、シートの構成を変更した事に始まり、フォーム全体に変更をかけた為、自分の力量では修正に結構時間がかかりそうです。一応、フォームの初期表示の修正は完成し、エラー等もなく思い通りの表示と動きになっています。
    ただ、何が影響しているのかが不明なので、全ての修正・見直しが終わってから、また、改めて今回のエラーの原因と向き合おうと思います。
    特に、普通の使用でエラーが出ることはなく、デバックの限られた状況のみです。
    補足の投稿回数も少なくなってしまった為、一旦この質問は打ち切りたいと思います。
    まだ、解決していませんが、長らくお付き合いしていただいたお礼にベストアンサーに選ばさせていただきます。
    どうも、ありがとうございました。

    No.7の回答に寄せられた補足コメントです。 補足日時:2019/01/14 01:29
gooドクター

A 回答 (7件)

最初に、もう確実なところはありませんので、推理して、それを実験でトライして確証を得るしかありませんが、まだ、私のネタ切れにはしばらくあります。



今、調べてみて、デバッグのコンパイルのボタンでエラーがでなくて、実際にはユーザー定義型のエラーが出てくるという例は聞いたことがないのです。

ちょっと脇道にそれますが、私自身のコードの作り方というのは、hinoki24さんのような真面目な作り方ではなく、
・Option Explicit は書いても、開発中はコメントブロックしてしまうということです。
・対応不足の予想を考えて、変数の宣言はしても、3分の1ぐらいは、Variant (つまり、 As ~ なし)にしてしまいます。

>このコード全体を、まずコメントブロックし、次に非コメントブロックで動作可能状態に戻し、該
>当シートのセルに文字を入力すると、ユーザー定義型は定義されていません、というエラーが1回
>はほぼ必ず発生しています。

Class は使っていませんか。シート1をインスタンスを作っているとか、
イベント・ドリブン型ですから、似たようなものだとは思います。他のイベントにしてみたらどうでしょうか?ダブルクリック・イベントとか。

標準モジュール側の Public 変数と、シートモジュールの 変数(Private)の、使い分けはないでしょうね。まあ、それをしてもユーザー定義型は定義されていない、というエラーはまずでないと思います。

また、私が考えたのは、オーバーヘッドの問題です。オーバーヘッドというのは、オブジェクトが設定されるまでには、多少の時間のロスがあります。だから、事前に参照設定(アーリー・バインディング)をしておけ、というわけです。だから、アーリー・バインディングか、レイト・バインディングか、という問題は、VBAテキストなどでは、前者が良いと書かれていますが、ブック全体で、それらのOLEオブジェクトを抱えていくのは無理な時があります。

それで、私は、このようにしてしまいます。
(インテリセンスが利かないとお思いでしょうが、最初は設定しておいて、後で、もとのオブジェクト型に戻すこともあります。今は、VBAのテンプレートを使うので不要で。)
Microsoft Scripting Runtime を参照設定する代わりに、 Set dic = CreateObject("Scripting.Dictionary") としてしまったり、

Microsoft VBScript Regular Expressions 5.5を参照設定する代わりに、Set Regex = CreateObject("VBScript.RegExp") で間に合わせてしまうことも多いです。

もう、同様の実験は済んでいるとは思いますが、いっそ、Sh As  Worksheet などのデータ型の宣言を、プロジェクト全体に対して、
「As」 ->「 'As」 で、置換して、どうなるでしょうか?

それでもエラーが出るとなると、一度コードを吐き出して、その中身を調べないといけないかもしれません。問題になっている Sheet1 のコードのエクスポートをさせて、テキストにして調べるのです。

他に、トラブルとして、名前登録があります。不要な名前登録は全部削除しておくと安心です。
それ以外は、アドインで、私製 comアドインなどが悪さをすることがあります。
以上、目下、思い当たる範囲です。
この回答への補足あり
    • good
    • 0
この回答へのお礼

どうもありがとうございました。
とりあえず、補足の回数もなくなった為終了します。
今のファイルは、エラーは出ていないですが、修正途中の所もあるので、検証していくにはとりあえず、完成させてからだと思いました。
後は、おっしゃるように、色々削っていって、絞り込んでみようと思います。
とりあえず、名前等を含めシートの方には問題ないようでした。今回ある程度までは絞り込んだので、完成したら、さらに絞り込んでいこと思います。
また、今回の現象は、デバックの限られた状況でエラーが出るのみで、実使用ではエラーは出ないようなので(多分)、使おうと思えば使えるかな、と思います。でも、できれば直したいですけど。

お礼日時:2019/01/14 01:40

その補足で書かれたコードは、私のイメージどおりなのですがいかがでしょうか。


いわゆる レイト・バインディングをお使いになったわけですね。

>列非表示のマクロは何か変な所があるでしょうか?エラーは無。
行の非表示というのはありますが、列の非表示というのは、グループ化しない限りは、使ったことがありませんね。
それでも、確か、結合セルと、その結合セルより右にある列の操作とにはなにかトラブルがあった気がしますね。でも、それと今回のものとは関係があるかわかりません。
この回答への補足あり
    • good
    • 0

こんばんは。



>質問にだしたシートのPrivate Sub Worksheet_Change(ByVal Target As Excel.Range)のみ残し....

思惑とは違うかもしれませんが、前回書いたものを訂正した、以下のコードを試してみてください。

それと、実行する前に、VBAEditor のメニューのデバッグで
VBAProjectのコンパイルをクリックしてください。

Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Column > 1 And Target.Column < 4 Then
  Call ABCD
End If
End Sub

'-----------------------------------
Microsoft Active Data Objects 6.1 Library
これは、つい、こちら側を選びたくなりますが、2.x 系のほうが新しいようです。
その差異はないとは思いますが。
-------------------------------------
それから、私の記憶では、参照設定が、うまくかみ合っていない可能性があります。その場合は、いったん、外して、再度、設定してみたらいかがでしょうか。

Visual Basic For Applications ×
Microsoft Excel 15.0 Object Library ×
OLE Automation  ?
Microsoft Office 15.0 Object Library ×
========================
Microsoft Forms 2.0 Object Library ×
========================
Microsoft VBScript Regular Expressions 5.5

Microsoft Active Data Objects 6.1 Library  (2.x系?)
Microsoft Scripting Runtime
-----------------------------
この回答への補足あり
    • good
    • 0

其のエラーを 検索したところ、


此の様な 記事を、
見つけましたが、
https://tsware.jp/tips/tips_334.htm

此は もう、
試されてますよね。
この回答への補足あり
    • good
    • 0

こんにちは。



「ユーザー定義型は定義されていません」というのは、
参照設定でサポートされていないオブジェクトなどの型名を定義した時に限ります。
(ユーザー定義型を定義する場合は除きますし、それは使わないです。)

簡単な例ですと、
Dim ws As Wokksheet  '←スペルミス
と書けば、確実に出てきます。Worksheet のスペルミスだからです。

MS(だけではないけれども)は、こういうプログラマーのために、インテリセンスをつけていますから、ws As として、スペースを入れれば、次に、その必要なものをリスト内から選べばよいわけです。それに出てこないものは、エラーとして現れます。

>ユーザー定義型は定義されていません、というエラーが1回はほぼ必ず発生しています。
>エラーがでても、そのままOKを押すと、コード自体は問題なく実行処理される。
そのまま次に進むのは、 On Error Resume Next のせいではありませんか?

単純なコードにまで On Error Resume Next を入れているのが目につきます。デバッグの段階で、On Error Resume Next では、さっぱり原因がつかめません。一番良いのは、エラーを出して、デバッグモードにさせて、その箇所を特定化させることです。

なお、私なら、こう書くかと思います。

'シートモジュール
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
If Target.Column > 1 And Target.Column < 4 Then
  Call ABCD
End If
End Sub
(ただし、ABCDの中味にイベントが発生するものは、
Application.EnableEvents=False
'実行プログラム
Application.EnableEvents=True
として、短い間を挟むようにします。長い間だと、別なエラーが発生した時に復旧が効かなくなります。

>Private Sub Worksheet_Deactivate()
>On Error Resume Next
>If あいう.Visible = True Then Unload あいう
>End Sub

これは、ユーザーフォームのことだと思います。私は、こういうコードは書かないけれども、これで動く分には問題ないはずです。
この回答への補足あり
    • good
    • 0

少なくとも、


ユーザー定義方は 存在しますよ?

http://officetanaka.net/excel/vba/statement/Type …
この回答への補足あり
    • good
    • 0

ABCDはどこに?

この回答への補足あり
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

gooドクター

このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング