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

Симптомы

Это особый симптом при компиляции проекта 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? Как люди находят эту оскорбительную строку кода, если они не могут отлаживать то, что им нужно изменить? Любая помощь будет прекрасна!

Спасибо заранее.

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

Ответы

Ответ 1

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

Мое дело: у меня есть .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")

Ответ 2

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

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

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

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

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

Ответ 3

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

Ответ 4

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

Ответ 5

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

Ответ 6

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

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

Если у вас есть какие-то нестандартные тусклые изображения google и посмотрите, отсутствует ли ссылка на эту библиотеку под инструментами.

-E

Ответ 7

Для справок в будущем -

У меня была эта проблема с этим фрагментом кода в 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

Ответ 8

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

Ответ 9

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

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

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

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

Ответ 10

Для типа 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

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

Ответ 11

Поздняя привязка

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

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

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

Ответ 12

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

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

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

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

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

Джим Льюдке

Ответ 13

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

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

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

Ответ 14

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

Ответ 15

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

Ответ 16

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

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

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

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

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

Но что в конечном итоге решило проблему:

  • В VBE - Копирование всего кода из модуля кода формы
  • В окне "Открыть открытую форму в представлении" установите значение Имеет ли модуль значение Нет
  • Сохранить проект (это удаляет любой код, связанный с формой)
  • (Не уверен, что нужно закрыть и снова открыть Access, но я это сделал)
  • Открыть форму в представлении "Дизайн" и установить Имеет ли модуль свойство Да
  • В VBE вставьте обратно скопированный код модуля
  • Сохранить

Ответ 17

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

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