web-dev-qa-db-ja.com

Excel VBAコンパイルは「ユーザー定義型が定義されていません」エラーをスローしますが、問題のあるコード行には移動しません

症状

これは、特にExcel VBAプロジェクトをコンパイルするときの症状です。次のエラーが発生します。

User-defined type not defined

ただし、このエラーを生成するコードはコンパイラによって強調表示されないため、問題を特定できません。

私がすでに知っていて試したこと

これは、以前にAs StrigではなくAs Stringという名前を付けるなどの簡単な問題で見た「ユーザー定義型が定義されていません」エラーです。ただし、この特定のエラーはDebug > Compile VBAProjectメニューオプション中にのみポップアップし、エラーメッセージボックスがポップアップするとき、エラーが発生しているコード行を強調表示しません。

多くの調査の結果、このバグは参照の欠落に関連している可能性があり、必要なすべての参照とツールボックスオブジェクトを含めたため、これを除外しました。

明らかな欠落しているDimステートメントが欠落していないことを確認するために、すべてのコードページ(フォームを含む)にOption Explicitを追加して、欠落がないことを確認しました。コンパイルを実行すると、エラーが引き続き表示されます。

この既知のバグもあります バイナリ互換性を使用するVB6プロジェクトが原因で問題が発生することがわかっていることを示しています:

バイナリ互換性をオフにして、プロジェクトをコンパイルします。 Visual Basicは、定義されていないユーザー定義型を含むコード行を強調表示します。問題を解決した後、バイナリ互換性をオンに戻すことができます。

この記事は 質問と回答 から見つけましたが、標準のExcelにはこのオプションがありません[〜#〜] vba [〜#〜]エディター。

私と他の人の正気を救う助けて!

Google検索やその他の質問から、この問題を抱えているのは私だけではないことがわかります。

コードを手動で試してみましたが、行が多すぎて実行できません。

Excel VBAプロジェクトでバイナリ互換性をオフにする方法はありますか?変更する必要があるものをデバッグできない場合、この問題のあるコード行をどのように見つけるのでしょうか?どんな助けも素敵です!

前もって感謝します。

編集: 問題のコード行を見つけたので、私の特定の問題は解決しました 特定の行を削除した後も問題はここにあります。コードで参照されているフォーム上のコントロール名のスペルミスです。これは、この問題のコードが問題であると特定する方法に関する特定の問題を解決するものではありません。このバグが発生したときに問題のあるコードを見つける良い方法を見つけることができるので、将来他の人がこの苦痛を避けることができますか?

20

私の解決策は朗報ではありませんが、少なくとも機能するはずです。

私の場合:同僚からの.xlsmがあります。 1)私はそれを開いてボタンをクリックします:それはうまく機能します。 2)ファイルを保存し、Excelを閉じて、もう一度ファイルを開きます。今はもう機能しません。結論は次のとおりです。コードは問題ありませんが、Excelは参照を正しく管理できません。 (私は成功せずに参照を再追加することを削除しようとしました)

そのため、解決策は、参照されるすべてのオブジェクトをVariantとして宣言し、_New Foo.Bar_の代わりにCreateObject("Foo.Bar")を使用することです。

例えば:

_Dim objXML As MSXML2.DOMDocument
Set objXML = New MSXML2.DOMDocument
_

と取り換える:

_Dim objXML As Variant
Set objXML = CreateObject("MSXML2.DOMDocument")
_
7
jng

あなたは多くの異なる潜在的な解決策を試したように聞こえるので、おそらくあなたはおそらくこれを長い系統的な方法で行う必要があります。

新しい空白のブックを作成します。次に、古いワークブックを少しずつコピーします。参照を追加し、それをテストするために少しのコードを記述します。コンパイル、実行を確認してください。サブルーチンまたは関数を追加し、再度、それを実行するための小さなテストサブを作成し、コンパイルを確認します。このプロセスを繰り返して、すべてを追加してテストします。

最初に大きなチャンクを試し、次に問題を引き起こすものを見つけたら、それを削除し、テストのために小さなピースに分割することで、これを少しスピードアップできます。

違反者を見つけるか、魔法のように問題のない新しいブックを作成します。後者は、ワークブックファイル、おそらくバイナリvbproject部分にある種の隠れた破損が原因です。

デバッガーやその他の便利なツールを使用せずにデバッグの世界にようこそ。

4
AndASM

私はまったく同じ問題を抱えていました(インターフェイスをユーザーフォームに実装しようとすると常に発生するようです。 here からCode Cleanerをダウンロードしてインストールします。これは、何度も助けてくれたフリーウェアユーティリティです。 VBAプロジェクトを開いた状態で、"Clean Code..."オプション。クリーンを実行する前に、「バックアッププロジェクト」および/または「すべてのコードモジュールをエクスポート」を安全な場所に確認してください。私の知る限り、このユーティリティはすべてのモジュールとクラスをエクスポートしてから再インポートします。これにより、コードに潜り込んだコンパイラエラーがなくなります。私にとって魅力のように働いた!幸運を。

3
user3803315

似たような経験がありましたが、クラスの1つで列挙型の名前を変更したためです。古い列挙型を参照していたクラスをエクスポートして再インポートすると、エラーメッセージが消えました。これは、VBA環境でのキャッシュの問題であることを示唆しています。

2
Rob Bishop

私にもこの問題があったことを知らせてください。問題はコードではなく、ボタンが呼び出していたマクロにありました。 (「createroutes.createroutes」マクロを呼び出していましたが、「createroutes」モジュールの名前を「routes」に変更しました。)したがって、ボタンを正しい場所に向けることで問題は修正されました。

2
Cameron Bradley

私はエラーを修正することができました

  1. Accessを完全に閉じる
  2. データベースファイルの名前を変更する
  3. 名前を変更したデータベースファイルをAccessで開きます。
  4. さまざまなセキュリティ警告とプロンプトを受け入れました。
    • マクロを有効にするだけでなく、名前を変更したデータベースを信頼済みドキュメントにすることも受け入れました。
    • 以前のファイルも信頼済みドキュメントとしてマークされていました。
  5. VBAプロジェクトをエラーなしで正常にコンパイルし、コードを変更しません。
  6. コンパイルが成功した後、Accessを再び閉じて、元のファイル名に戻すことができました。同じセキュリティプロンプトに返信する必要がありましたが、VBAプロジェクトを開いてもエラーなしでコンパイルされたままでした。

このケースの少しの歴史と観察:

  • 私が観察した症状は他の症状とは少し異なっていたため、および/または私の解決策はユニークだと思われるため、この回答を投稿しています。
  • 少なくとも私がエラーを経験した時間の一部の間、私のVBAウィンドウには2つの余分な「神秘的な」プロジェクトが表示されていました。残念ながら、エラーを解決する前に名前を記録しませんでした。 1つはACXTOOLSのようなものでした。内部のモジュールを開けませんでした。
  • モジュールコードを更新する前にフォームに大きな変更を加えていたため、元の問題は実際に悪いコードによるものだと思います。しかし、コードを修正した後でもエラーは続きました。フォームが読み込まれ、エラーが発生しないため、コードが機能することはわかっていました。元の投稿にあるように、「ユーザー定義型が定義されていません」エラーが表示されますが、問題のあるコード行には移動しません。
  • このエラーを見つける前に、必要な参照がすべて追加されていることを確認しました。データベースを複数回圧縮および修復しました。さまざまな修正を試行するたびに、Accessを閉じてファイルを何度も開きました。問題の疑わしいフォームを削除しましたが、まだエラーが発生しました。ここや他のフォーラムで提案されている他のさまざまな手順を試しましたが、問題を解決できるものはありません。
  • 一度に1つのフォーム/モジュールを削除するなどの抜本的な対策を試みるためのバックアップコピーを作成したときに、この修正につまずきました。しかし、バックアップコピーを開くと、問題は再発しませんでした。
1
C Perkins

考えられる解決策は、Excel VBA経由でPowerPointを使用しようとしていて、最初にPowerPointオブジェクトライブラリをアクティブ化していないことです。

これを行うには、VBAエディターのトップメニューで[ツール]、[参照設定]を選択し、下にスクロールして[Microsoft PowerPoint xx.xオブジェクトライブラリ]というライブラリーをクリックします。 Office 2007はライブラリ12で、各Officeバージョンには異なるライブラリがあります。参考までに、2007ライブラリをアクティブにすると、いくつかの奇妙なエラーとファイルの破損が発生しましたが、誰かがExcel 2003を使用してこのマクロを開いて実行しようとしています。

1
Nathalii.

通常のVB6プログラムでこの問題が発生しました。ユーザー定義型ではなく、クラス定義を省略したことが判明しました。どうやらVBは「Thing.name」のようなものを見て、ThingはUDTであると想定しました。関係するさまざまな製品のどのバージョンを使用していますか?これは、MSがサポートする製品で発生する場合にのみ興味深いものです。

1
user3818635

私はこれが古いことを知っていますが、同様の問題があり、修正を見つけました:

ExcelからAccessに移植したモジュールと同じ問題があり、無関係なUDFで「範囲として」を暗くしていましたが、Accessに範囲が存在しません。適切な参照ライブラリを有効にせずに変数タイプを使用している可能性があります。

非標準のdimsがある場合はそれらをグーグルで検索し、そのライブラリへの参照がツールの下にないかどうかを確認します。

-E

1
Schalton

将来の参考のために -

コメント付きの行を強調表示するデバッガーで、Microsoft Accessのこのコード部分でこの問題が発生しました。

Option Compare Database
Option Explicit

Dim strSQL As String
Dim rstrSQL As String
Dim strTempPass As String


Private Sub btnForgotPassword_Click()
On Error GoTo ErrorHandler

Dim oApp As Outlook.Application '<---------------------------------Offending line
Dim oMail As MailItem
Set oApp = CreateObject("Outlook.application") 'this is the "instance" of Outlook
Set oMail = oApp.CreateItem(olMailItem) 'this is the actual "email"

以前は選択されていなかった参照を選択する必要がありました。彼らはいた

Microsoft Outlook 15.0オブジェクトライブラリ
Microsoft Outlookビューコントロール

1
Mark

Scripting.Dictionaryタイプの場合、(既に指摘したように)遅延バインディングを次のいずれかで使用できます。

Dim Dict as Object
Set Dict = CreateObject("Scripting.Dictionary")

これは機能しますが、コードの自動補完を取得できません。または、事前バインディングを使用しますが、VBA-> Tools-> References-> "Microsoft Scripting Runtime"を介してMicrosoft Scripting Libraryへの参照を追加することにより、VBAがScripting.Dictionary型を検出できることを確認する必要があります。次に使用できます:

Dim Dict as Scripting.Dictionary
Set Dict = New Scripting.Dictionary

...自動補完が機能します。

1
RexBarker

Microsoft Scripting Runtimeを有効にすると、同じ問題が発生します。 [ツール]> [参照]で設定し、Microsoft Scripting Runtimeのチェックボックスをオンにします。これで問題が解決するはずです。

0
Vincent

同じ症状の別の問題:定義されていないクラスを実装しました。 #ifでラップされていたので、コンパイラーがそれを見ることができないようにすべきでしたが、そうではありませんでした。 Implementsステートメントからコメントを削除すると、すべてが順調です。定義のインポートも機能すると思います...

0
Ed Hoeffner

昨日、同じエラーが発生しました:私のプロジェクトにはcProgressとcProgressExの2つのクラスがあり、そのうちの1つは使用されなくなりました。cProgressクラスを削除すると、同じコンパイルエラーが発生しました。

私は次のようにエラーを修正することができました:

  • すべてのモジュール、フォーム、およびクラスをハードドライブにエクスポートしました
  • プロジェクトからすべてを削除しました
  • プロジェクトを保存しました
  • すべてのモジュール、フォーム、クラスを再インポートし、cProgressクラスを削除してコンパイルしました。
  • エラーが消えました。
0

別のアナリストのワークブックを継承したときにも、同じ問題が発生しました。彼はワークシートの各ボタンにマクロを割り当てました。モジュールの名前(プロシージャ名ではない)を変更すると、このエラーが発生しました。修正は簡単でした。ボタンでワークシートの_OnClick()イベントプロシージャを実行し、そのプロシージャを明示的にCall MyProcedureName()させます。

0
Mark Bauer

MS Accessデータベースでこのエラーが発生したとき、Compact/Repairオプションとともに/ decompileコマンドラインスイッチを使用しました。私のために働いた。私は自分のコードがもう使用されていないと確信している参照を削除し、このエラーを取得し始めました。

0
UtilizeIT

数年後、Excelの「ユーザー定義型が定義されていません」エラーのMicrosoftバグへの答えを見つけました。 Windows用のExcel 2010を実行しています。

たとえば「xyz()」という名前のUDFがある場合、その名前で始まる存在しないエンティティを呼び出した場合ピリオドの後に他の文字が続きます-たとえば、nonを呼び出そうとした場合-既存の範囲名 'xyz.abc'、愚かなアプリはその間違ったメッセージをスローし、その後シートに戻ります。

私の場合、特に不安を感じました。なぜなら、1文字だけで名前が付けられたUDFがあるからです。 x()y()など。また、ピリオドを含む範囲名もあります--x.a '、' c.d 'など。たとえば、「x.h」などの範囲名のスペルを間違えるたびに、「x()」という名前のUDFがプロジェクトのどこかに存在するため、「ユーザー定義…」エラーがスローされました。

数時間かかりました。診断する。プロジェクトからコードをインクリメンタルに削除する、または逆にすべてのコードをストリップしてからインクリメンタルに追加するという上記の提案は正しい軌道に乗っていましたが、それらは順守しませんでした。コード自体とは関係ありません。各procのコードの最初の行の名前、つまりprocを命名するSub MyProcまたはFunction MyProc行のみに関係します。プロジェクトの完全に無関係な部分で1文字の名前のUDFの1つをコメントアウトしたとき、エラーメッセージがバグになりました。離れて行き、そこからさらに1時間後に。または、述べたようにルールを一般化することができました。

おそらく、バグは句読点ピリオド( '.')以外でも発生しますが、範囲名に使用できる非アルファ文字はあまり多くありません。下線( '_')は許可されますが、説明されている方法で下線を使用してもバグはスローされないようです。

ジム・リュードケ

0
Jim Luedke

レイトバインディング

このエラーは、参照がないために発生する可能性があります。たとえば、参照を削除することにより、事前バインディングから遅延バインディングに変更するときに、削除された参照に固有のデータ型を参照するコードが残っている場合があります。

参照を含めて、問題が消えるかどうかを確認してください。

このエラーはコンパイラエラーではなく、リンカーエラーである可能性があるため、特定の行は不明です。マイクロソフトの恥!

0
jas0501

少し遅れて、完全な解決策でもありませんが、明白な理由(すべての参照が定義されているなど)なしにこのエラーに見舞われるすべての人にとって、このスレッドは私を正しい軌道に乗せました。この問題は、MS Office VBA Editorのキャッシュ関連のバグに起因するようです。

MS Access 2016でコードモジュールと40のクラスといくつかのグローバルモジュールを含む約40のフォームを含むプロジェクトにいくつかの変更を加えた後、コンパイルは失敗しました。

コードをコメントアウトすることは明らかに選択肢ではなく、80以上のすべてのファイルをエクスポートおよび再インポートするのは合理的ではありませんでした。最近変更されたことに集中して、私の疑いは1つのクラスモジュールの削除に焦点を合わせました。

より良いアイデアがなかったので、以前に削除された同じ名前の空のクラスモジュールを再作成しました。そして、エラーはなくなりました!エラーが再表示されることなく、未使用のクラスモジュールを再度削除することさえ可能になりました。これは、現在削除されたクラスに関連するWithEvents宣言を含むフォームモジュールに変更が保存されるまで続きます。

WithEvents宣言が、宣言が削除された後でもエラーを引き起こすものであるかどうかは完全にはわかりません。そして、どのフォームが犯人である可能性があるのか​​を実際に(開発履歴に関する情報なしで)見つける方法はわかりません...

しかし、最終的に問題を解決したのは:

  1. VBEの場合-フォームコードモジュールからすべてのコードをコピーします
  2. Accessでデザインビューでフォームを開き、Has ModuleプロパティをNoに設定します
  3. プロジェクトを保存します(フォームに関連付けられたコードが削除されます)
  4. (Accessを閉じて再度開く必要があるかどうかはわかりませんが、私はそれを行いました)
  5. デザインビューでフォームを開き、Has ModuleプロパティをYesに戻します
  6. VBEでコピーしたモジュールコードを貼り付けます
  7. セーブ
0
Kristian L