it-roy-ru.com

Компиляция Excel VBA выдает ошибку "Определяемый пользователем тип не определен", но не переходит в оскорбительную строку кода

Симптомы

Это особенно характерно при компиляции проекта Excel VBA. Возникает следующая ошибка:

User-defined type not defined

Однако код, который выдает эту ошибку, не выделяется компилятором, и поэтому я не могу определить проблему.

Что я уже знаю и попробовал

Это ошибка «Определяемый пользователем тип не определен», с которой я сталкивался ранее при простых проблемах, таких как присвоение имени As Strig вместо As String. Однако эта конкретная ошибка появляется только во время опции меню Debug > Compile VBAProject, и когда всплывает окно с сообщением об ошибке, оно не выделяет строку кода, в которой происходит ошибка.

После многих исследований я обнаружил, что эта ошибка может быть связана с отсутствующими ссылками, и я исключил это, так как включил все необходимые ссылки и объекты Toolbox.

Чтобы не пропустить ни одного очевидного пропущенного оператора Dim, я добавил Option Explicit ко всем кодовым страницам (включая формы), чтобы ничего не пропало. Ошибка по-прежнему отображается при запуске компиляции.

Существует также эта известная ошибка , которая утверждает, что проблема, как известно, произошла из-за проектов VB6, использующих двоичную совместимость:

Отключите двоичную совместимость и скомпилируйте проект. Visual Basic выделит строку кода, содержащую определяемый пользователем тип это не определено. После решения проблемы двоичная совместимость может быть включен обратно.

Я нашел эту статью с помощью этого Вопрос и ответ , однако я не могу найти эту опцию в стандартном редакторе Excel VBA.

Помогите спасти мое и чужое здравомыслие!

По поисковым запросам Google и другим вопросам я знаю, что я не единственный, у кого возникла эта проблема.

Я попытался пройти код вручную, но слишком много строк, чтобы это сделать.

Есть ли способ отключить двоичную совместимость в проектах Excel VBA? Как люди находят эту оскорбительную строку кода, если они не могут отладить то, что им нужно изменить? Любая помощь будет прекрасна!

Заранее спасибо.

Правка: Я нашел оскорбительную строку кода, и поэтому моя конкретная проблема решена Проблема все еще здесь после удаления этой конкретной строки - это было неправильное имя элемента управления в форме, на которую есть ссылка в его коде. Это по-прежнему не решает конкретную проблему того, как вы могли бы найти этот оскорбительный код. Можем ли мы найти хороший способ найти код, вызывающий ошибку, когда эта ошибка возникает, чтобы другие в будущем могли избежать этой агонии?

18
Tom 'Blue' Piddock

Мое решение не является хорошей новостью, но, по крайней мере, оно должно работать.

Мой случай таков: у меня есть .xlsm от коллеги. 1) Я открываю его и нажимаю кнопку: он работает нормально. 2) Я сохраняю файл, закрываю Excel, снова открываю файл: теперь он больше не работает. Вывод: код в порядке, но Excel не может правильно управлять ссылками. (Я попытался удалить повторное добавление ссылок без какого-либо успеха)

Таким образом, решение состоит в том, чтобы объявить каждый объект, на который ссылаются, как Variant и использовать CreateObject("Foo.Bar") вместо New Foo.Bar.

Например:

Dim objXML As MSXML2.DOMDocument
Set objXML = New MSXML2.DOMDocument

Заменен на:

Dim objXML As Variant
Set objXML = CreateObject("MSXML2.DOMDocument")
5
jng

Поскольку кажется, что вы пробовали много разных потенциальных решений, вам, вероятно, придется делать это длительным методическим путем сейчас.

Создайте новую пустую книгу. Затем по частям скопируйте в нее свою старую рабочую книгу. Добавьте ссылку, напишите немного кода, чтобы проверить ее. Убедитесь, что он компилируется, убедитесь, что он работает. Добавьте подпрограмму или функцию, снова напишите небольшую подпрограмму для ее запуска и убедитесь, что она компилируется. Повторите этот процесс, медленно добавляя и тестируя все.

Вы можете немного ускорить это, сначала попробовав большие куски, а затем, когда найдете тот, который вызывает проблему, удалите его и разбейте на более мелкие кусочки для тестирования.

Либо вы найдете преступника, либо у вас будет новая рабочая тетрадь, которая по волшебству не имеет проблемы. Последнее будет связано с неким скрытым повреждением в файле рабочей книги, возможно, в двоичной части vbproject.

Добро пожаловать в мир отладки без отладчиков и других полезных инструментов, которые сделают тяжелую работу за вас!

4
AndASM

Был похожий опыт, но это было потому, что я переименовал enum в одном из моих занятий. Я экспортировал и повторно импортировал классы, которые ссылались на старое перечисление, и сообщение об ошибке исчезло. Это говорит о том, что это проблема кэширования в среде VBA.

2
Rob Bishop

У меня была точно такая же проблема (кажется, всегда возникает, когда я пытаюсь реализовать интерфейс на пользовательской форме. Загрузите и установите Code Cleaner из здесь . Это бесплатная утилита, которая спасла меня во многих случаях. С вашим VBA открыть проект, запустите опцию "Clean Code...". Убедитесь, что вы проверили «проект резервного копирования» и/или «экспортировали все модули кода» в безопасные места перед запуском clean. Насколько я понимаю, эта утилита экспортирует, а затем повторно импортирует все модули и классы, которые устраняют ошибки компилятора, которые проникли в код. Работали как обаяние для меня! Удачи.

2
user3803315

Просто сообщаю всем вам, что у меня тоже была эта проблема. Проблема заключалась не в коде, а в том, какой макрос вызывает кнопка. (Он вызывал макрос «createroutes.createroutes», но я переименовал модуль «createroutes» в «маршруты».) Поэтому проблема была исправлена ​​путем указания кнопки в правильном месте.

2
Cameron Bradley

Я смог исправить ошибку 

  1. Полностью закрывающий доступ 
  2. Переименование файла базы данных
  3. Открытие переименованного файла базы данных в Access.
  4. Принимаются различные предупреждения и подсказки по безопасности .
    • Я не только решил включить макросы, но и принял решение сделать переименованную базу данных доверенным документом.
    • Предыдущий файл также был помечен как доверенный документ.
  5. Успешно скомпилируйте проект VBA без ошибок, без изменений в коде.
  6. После успешной компиляции я смог снова закрыть Access и переименовать его обратно в исходное имя файла. Я должен был ответить на те же самые запросы безопасности, но как только я открыл проект VBA, он все еще компилировался без ошибок.

Немного истории этого случая и наблюдений:

  • Я публикую этот ответ, потому что мои наблюдаемые симптомы немного отличаются от других, и/или мое решение кажется уникальным.
  • По крайней мере, в течение части времени, когда я сталкивался с ошибкой, мое окно VBA показывало два дополнительных, «таинственных» проекта. К сожалению, я не записывал имена, пока не решил ошибку. Один был чем-то вроде ACXTOOLS. Модули внутри не могут быть открыты.
  • Я думаю, что исходная проблема действительно была из-за плохого кода, так как я внес серьезные изменения в форму, прежде чем пытаться обновить ее код модуля. Но даже после исправления кода ошибка сохранилась. Я знал, что код работал, потому что форма будет загружаться и без ошибок. Как говорится в исходном сообщении, появится сообщение об ошибке «Определяемый пользователем тип не определен», но оно не попадет ни в какую строку кода.
  • Прежде чем найти эту ошибку, я убедился, что все необходимые ссылки были добавлены. Я сжал и восстановил базу данных более одного раза. Я закрывал Access и повторно открывал файл несколько раз между различными попытками исправления. Я удалил подозреваемую форму оскорбления, но все еще получил ошибку. Я пробовал другие различные шаги, предложенные здесь и на других форумах, но ничего не решило проблему.
  • Я наткнулся на это исправление, когда сделал резервную копию для попыток радикальных мер, таких как удаление одной формы/модуля за раз. Но при открытии резервной копии проблема не повторялась.
1
C Perkins

Возможное решение: вы пытаетесь работать с PowerPoint через Excel VBA и сначала не активировали библиотеку объектов PowerPoint.

Для этого в верхнем меню редактора VBA выберите Сервис, Ссылки, затем прокрутите вниз, чтобы щелкнуть библиотеку под названием Microsoft PowerPoint xx.x Object Library. Office 2007 - это библиотека 12, каждая версия Office имеет свою библиотеку. К вашему сведению, я столкнулся с некоторыми странными ошибками и повреждением файла, когда я активировал библиотеку 2007 года, но кто-то пытается открыть и запустить этот макрос с помощью Excel 2003. Старая версия Excel не распознает более новую библиотеку, что, кажется, вызывает проблемы.

1
Nathalii.

У меня была эта проблема с обычной программой VB6. Оказалось, что я опустил определение класса, а не пользовательский тип. Видимо VB увидел что-то вроде «Thing.name» и предположил, что Thing был UDT. Да, это серьезная ошибка VB6, но вряд ли стоит ожидать, что Microsoft поддержит то, что они продали шестнадцать лет назад. Итак, какие версии различных продуктов вы используете? Это только интересно, если это происходит с продуктом, который поддерживает MS. 

1
user3818635

Я знаю, что это старый, но у меня была похожая проблема, и я нашел решение:

У меня была такая же проблема с модулем, который я перенес из Excel в Access, в несвязанном UDF я затемнял «As Range», но диапазоны не существуют в Access. Вы можете использовать тип переменной, не имея соответствующей справочной библиотеки.

Если у вас есть какие-то нестандартные цвета, поищите их в Google и посмотрите, не отсутствуете ли вы ссылку на эту библиотеку в разделе инструментов.

-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 View Control

1
Mark

Для типа Scripting.Dictionary вы можете использовать позднюю привязку (как уже отмечалось) с:

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

Что работает, но вы не получите код автозаполнения. Или вы используете раннее связывание, но вам нужно убедиться, что VBA может найти тип Scripting.Dictionary, добавив ссылку на библиотеку сценариев Microsoft через VBA -> Инструменты -> Ссылки -> «Среда выполнения сценариев Microsoft». Тогда вы можете использовать:

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

... и автозаполнение будет работать.

1
RexBarker

У меня была такая же проблема: если вы включите Microsoft Scripting Runtime, у вас все будет хорошо. Вы можете сделать это в разделе инструменты> ссылки> и затем установить флажок для Microsoft Scripting Runtime . Это должно решить вашу проблему.

0
Vincent

Другая проблема с тем же симптомом: у меня был реализован класс, который не был определен. Он был обёрнут #if, который, как я думал, не позволил компилятору увидеть его, но не так. Удалите комментарий из оператора реализует, и все хорошо. Я предполагаю, что импорт определения также будет работать ...

0
Ed Hoeffner

У меня вчера была та же ошибка: у меня было два класса, cProgress и cProgressEx, в моем проекте, один из которых больше не использовался, и когда я удалил класс cProgress, мне выдали ту же ошибку компиляции.

Мне удалось исправить ошибку следующим образом:

  • Экспортировал все модули, формы и классы на жесткий диск
  • Удалено все из проекта
  • Сохраненный проект
  • Повторно импортировал все модули, формы и классы, удалил класс cProgress и скомпилировал. 
  • Ошибка исчезла.
0
Stanislav Okhvat

Спустя годы я обнаружил один, если не ответ на ошибку Microsoft об ошибке «Определенный пользователем тип не определен» в Excel. Я использую Excel 2010 для Windows.

Если у вас есть UDF с именем, например, «xyz()», то если вы вызываете несуществующую сущность, начинающуюся с этого имени , за которой следует точка, за которой следуют другие символы - например, если вы пытаетесь вызвать несуществующий диапазон name 'xyz.abc', глупое приложение выдает неправильное сообщение, после чего оно возвращает вас на ваш лист.

В моем случае это было особенно неприятно, потому что у меня есть UDF, названные только одной буквой, например, x(), y() и т. д., и у меня также есть имена диапазонов, которые включают точки -'x.a ',' c.d 'и т. д. Каждый раз, когда я, скажем, неправильно написал имя диапазона - например, , «x.h», ошибка «Пользовательский…» возникла просто потому, что где-то в моем проекте была UDF с именем x().

Это заняло несколько часов. для диагностики. Приведенные выше предложения по постепенному удалению кода из вашего проекта или, наоборот, удалению всего кода и добавлению его обратно, были на правильном пути, но они не выполнялись. Это не имеет ничего общего с кодом как таковым; он имеет отношение только к имени первой строки кода в каждом процессе, а именно к строке Sub MyProc или Function MyProc с именем proc. Именно когда я закомментировал один из моих однобуквенных UDF в совершенно не связанной части проекта, появилась ошибка с сообщением msg. ушел и оттуда, через еще час. или так, я смог обобщить правило, как указано.

Возможно, ошибка также возникает с символами пунктуации, отличными от точки ('.'), но в имени диапазона допустимо не так много символов без альфа; подчеркивание ('_') разрешено, но его использование описанным способом, похоже, не приводит к ошибке.

Джим Луедке

0
Jim Luedke

Позднее связывание 

Эта ошибка может возникнуть из-за отсутствия ссылки. Например, при переходе от раннего связывания к позднему связыванию путем исключения ссылки может остаться некоторый код, который ссылается на типы данных, специфичные для отброшенной ссылки.

Попробуйте включить ссылку, чтобы увидеть, если проблема исчезнет.

Может быть, ошибка не ошибка компилятора, а ошибка компоновщика, поэтому конкретная строка неизвестна. Позор Microsoft!

0
jas0501

Немного опоздал, и тоже не полное решение, но для всех, кто столкнулся с этой ошибкой без какой-либо очевидной причины (с определением всех ссылок и т.д.). Этот поток поставил меня на правильный путь. Эта проблема возникает из-за ошибки, связанной с кэшированием в редакторе MS Office VBA.

После внесения некоторых изменений в проект, включая около 40 форм с модулями кода плюс 40 классов и некоторые глобальные модули в MS Access 2016, компиляция не удалась. 

Комментирование кода, очевидно, не было вариантом, и экспорт и повторный импорт всех файлов более 80+ не казался разумным. Сосредоточив внимание на том, что было недавно изменено, мои подозрения были сосредоточены на удалении одного модуля класса. 

Не имея лучших идей, я заново создал пустой модуль класса с тем же именем, которое было ранее удалено. И, наконец, ошибка исчезла! Можно было даже снова удалить неиспользуемый модуль класса без повторного появления ошибки, пока все изменения не были сохранены в модуле формы, который ранее содержал объявление WithEvents, включающее теперь удаленный класс.

Не совсем уверен, действительно ли объявление WithEvents вызывает ошибку даже после удаления объявления. И нет никаких подсказок, как на самом деле выяснить (не имея информации об истории разработки), какая форма может быть виновником ...

Но то, что наконец решило проблему, было:

  1. В VBE - скопировать весь код из модуля кода формы
  2. В Access откройте форму в режиме конструктора и установитеИмеет модульсвойство в Нет
  3. Сохранить проект (при этом удаляется любой код, связанный с формой)
  4. (Не уверен, если нужно закрыть и заново открыть Access, но я сделал это)
  5. Откройте форму в представлении «Дизайн» и установитеИмеет модульсвойство обратно в Да
  6. В VBE вставьте скопированный код модуля
  7. Сохранить
0
Kristian L