Как получить информацию о типах данных 1С через COM Connector в C#?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Работа с 1С через COMConnector из среды .NET (C#) часто сопряжена с трудностями интерпретации типов данных. В отличие от нативного языка 1С, где метаданные доступны напрямую, в C# мы получаем объекты __ComObject или dynamic, свойства которых не всегда очевидны. Разберем подробно, как определить, какой тип данных скрывается за реквизитом, и как отличить простую строку от ссылки на справочник.

Понимание структуры типов в 1С

Прежде всего, проанализируем, что возвращает реквизит метаданных. В 1С свойство Тип у объекта метаданных реквизита возвращает объект ОписаниеТипов (TypeDescription). Важно помнить, что 1С поддерживает составные типы, поэтому ОписаниеТипов — это всегда коллекция, даже если выбран только один тип.

Рассмотрим базовый алгоритм получения типов на стороне C#:


// Предположим, 'connection' — это ваше COM-соединение (V83.COMConnector)
// 'propertyMetadata' — объект метаданных конкретного реквизита
dynamic typeDescription = propertyMetadata.Type; // ОписаниеТипов
dynamic typesArray = typeDescription.Types(); // Вызов метода Типы()
int count = typesArray.Count(); // Количество типов в составе

for (int i = 0; i < count; i++)
{
    dynamic currentType = typesArray.Get(i); // Получаем конкретный объект Тип
    // Дальнейшая логика анализа
}

Метод 1: Использование XML-сериализации для идентификации типа

Одним из самых простых и эффективных способов узнать строковое наименование типа в формате XML является использование методов глобального контекста 1С через объект соединения. Рассмотрим использование XMLString и XMLTypeOf. Эти методы позволяют получить строковый идентификатор, который легко обработать в C#.

Проанализируем пример кода, который поможет получить имя типа:


// Получаем строковое представление типа
string xmlTypeName = connection.XMLString(currentType); 
// Для простых типов это вернет что-то вроде "string", "decimal"
// Для ссылок — описание типа в формате XML

Однако стоит быть осторожными: вызов XMLString напрямую к объекту ОписаниеТипов может привести к ошибке. Всегда извлекайте конкретный Тип из коллекции Types(), как показано выше.

Метод 2: Определение ссылочных типов через метаданные

Если нам нужно выяснить, является ли тип ссылочным (например, СправочникСсылка или ДокументСсылка), и получить доступ к его метаданным, лучше всего использовать метод FindByType объекта Metadata. Это наиболее профессиональный подход.

Разберем этот процесс по шагам:

  1. Получаем объект Тип из ОписаниеТипов.
  2. Передаем этот объект в connection.Metadata.FindByType().
  3. Если результат не равен null, перед нами ссылочный тип, и мы можем прочитать его полное имя.

Посмотрим на программную реализацию:


dynamic foundMetadata = connection.Metadata.FindByType(currentType);
if (foundMetadata != null)
{
    string fullName = foundMetadata.FullName(); // Например, "Справочник.Номенклатура"
    string synonym = foundMetadata.Synonym;
    Console.WriteLine($"Это ссылка: {fullName} ({synonym})");
}
else
{
    Console.WriteLine("Это простой тип (строка, число, дата или булево)");
}

Метод 3: Использование функции ТипЗнч и строковых представлений

Иногда полезно получить информацию о типе уже имеющегося значения (объекта), а не просто описание из метаданных. В 1С для этого служит функция ТипЗнч. При работе через COM её необходимо вызывать у объекта соединения.

Выясним причину, почему прямой вызов может не работать: в C# необходимо следить за языком интерфейса. Если COM-соединение инициализировано с поддержкой английского, лучше использовать TypeValue. Однако самым надежным способом будет использование функции String() для получения человекочитаемого названия типа.


// Получаем значение реквизита
dynamic value = objectRef.Description; 
// Получаем тип значения
dynamic typeOfValue = connection.TypeValue(value);
// Преобразуем тип в строку для анализа
string typeString = connection.String(typeOfValue); 
// Вернет "Строка" или "Справочник ссылка: Номенклатура"

Важные рекомендации при работе с COM Connector

Используйте англоязычные аналоги методов. Рассмотрим ситуацию: при вызове .Типы() в некоторых версиях C# и настройках локали могут возникать ошибки. Использование .Types(), .Count(), .Get() вместо .Получить() делает код более стабильным при работе через COM-интерфейс.

Обработка Null и Неопределено. В 1С существуют специфические значения Null и Неопределено. В C# они могут приходить как DBNull.Value или специфические COM-объекты. Перед анализом типа всегда проверяйте значение:


if (value == null || value is DBNull) 
{
    // Обработка пустого значения
}

Выполнение кода на стороне 1С. Если логика определения типа становится слишком сложной для реализации на C#, мы можем воспользоваться методами Вычислить() (Eval) или Выполнить() (Execute) самого соединения. Это позволит перенести часть логики непосредственно в среду 1С, вернув в C# уже готовый результат (например, строку или булево значение).


// Пример использования Eval для проверки на тип
bool isNomenclature = connection.Eval($"ТипЗнч(Объект) = Тип(\"СправочникСсылка.Номенклатура\")");

Подводя итог, можно сказать, что работа с типами через COM требует понимания того, что почти любая операция должна проходить через объект connection. Не пытайтесь обращаться к методам типа напрямую в C#, так как они не являются частью интерфейса IDispatch объекта типа, а являются функциями глобального контекста 1С.

← На главную