Pull to refresh

Comments 8

Для меня самым чувствительным недостатком этой фичи является то, что UDT нельзя присваивать в variant переменную, и как следствие - нельзя использовать в словарях и коллекциях (а можно только в массиве, что менее удобно при динамичесом добавлении/удалении элементов).

Я так понимаю, что это ограничение обусловлено переменным размером UDT в памяти, и так как это значимый тип, его нельзя запихнуть в переменную Variant фиксированного размера (16 байт вроде). Знающие люди, подскажите - есть ли обходной путь (например что-то вроде аналога boxing из C#)?

Насколько мне известно, увы да, udt нельзя добавить в collection или в dictionary.

Только массив, Вы правы.

Как альтернатива - создать класс, аналогично udt. В данном случае будет более гибкая модель.

именно поэтому просто создаю классы - удобней во всех отношениях. . Читал статью и все думал - в чем преимущество перед классом? И не увидел.

Ну, на самом деле, с такими мыслями можно и от ООП отказаться в пользу ФП, а вместо Enum пользоваться константами. Да и они не нужны, просто в процедуре присваивать значения, да и все :)

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

Ну и мое сугубо личное мнение - если в языке есть функционал, надо его как минимум знать, а в идеале использовать (не просто же так его завезли). Могу быть не прав, но на то это и сугубо личное мнение.

Ни в коем случае не камень, и не в Ваш огород. Просто размышления в слух.

P.S. Кстати, в статье я не пытаюсь сравнить Type с Классом (в плане «что лучше, то или это»). А если создается такое ощущение, то оно ложное, отбросьте его :)

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

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

Это еще что - значительная часть не пользуется и массивами. Залезаешь в чужой код - а там - "вротмненоги" - массив с листа на лист переносится поячеечно с переключением между листами и книгами.

Еще радуют деятели, которые в Outlook'e пытаются в одну строчку программно написать HTMLBody - то есть. проставить все возможные тэги вместо того. чтобы просто сделать шаблон и менять в нем кусочек или же, наконец. через подключить инспектор и нафигачить как документ Word.

P.S. к вопросу, функции вместо классов часто бывают полезней. Например, в функцию проще передать локальную переменную.

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

Часть I. Кто виноват.

Сообщение об ошибке

Microsoft Visual Basic for Applications

Compile error:

Only user-defined types defined in public object modules can be coerced to or from a variant or passed to late-bound functions

вроде бы намекает на способ решения этой задачи. Дьявол, как всегда, в деталях. Во-первых, модуль класса с Instancing=2 (PublicNotCreatable) таки (казалось бы - Public!) не подходит для размещения описания Public Type. Во-вторых, в VBA нет для классов instancing-ов со значениями больше 2, например 5 (MultiUse). А вот в "полноценном" VB (5/6)

есть.

То есть сообщение об ошибке завезли из VB, но в VBA оно бесполезно и вводит в заблуждение.

Часть 2. Что делать.

(Опуская дискуссию о необходимости)

Сделать в VBA-проекте ссылку (Tools\References...) на библиотеку типов, в которой описан UDT. Нюанс: у типа обязан быть uuid. Так что VB6/IDL+midl/Delphi/C#/etc. в руки для создания отдельных .tlb или .dll/.exe/.ocx с ресурсом соответствующего типа внутри.

Исходник простейшей библиотеки на IDL
[
  uuid(3CABBB90-BB91-4133-9FA1-5E443BEF2D7B),
  version(1.0)
]

library MyTypeLib
{
    // TLib :     // TLib : OLE Automation : {00020430-0000-0000-C000-000000000046}
    importlib("stdole2.tlb");

    typedef [uuid(B5F4AEAD-2657-4D2E-A6B6-AD3CFE0102C5), version(1.0)]
    struct tagAlterParams {
        [helpstring("NameFrmWork")]
        BSTR NameFrmWork;
        [helpstring("LineId")]
        long LineId;
        [helpstring("TypeComm")]
        long TypeComm;
        [helpstring("TypeWork")]
        long TypeWork;
    } AlterParams;
};

Круто, спасибо за интересную информацию!

Sign up to leave a comment.

Articles