Перевірити наявність реквізита в шапці

Відповісти
Inkognito
Повідомлень: 1067
З нами з: 14 січня 2012, 14:26

Перевірити наявність реквізита в шапці

Повідомлення Inkognito » 15 грудня 2021, 11:01

Проблема:
Якщо спробувати отримати реквізит, якого немає в документі, - Медок закривається:
док = App.OpenDocumentByCode(CardCode);
дс = док.DataSets("MAIN");
Відповідальний = дс.FldVal("SIDE_OTV_FIO"); //відповідальна особа контрагента. Тут Медок вилітає, якщо реквізит відсутній

Питання: як перевірити наявність реквізиту в DataSets(), перед спробою його отримати?
Аналог ЕстьРеквизит() для 1С | Показать
Если ЕстьРеквизит("SIDE_OTV_FIO", МетаданныеДокумента) Тогда
Відповідальний = Документ.SIDE_OTV_FIO;
КонецЕсли;

PetroP
Повідомлень: 714
З нами з: 22 січня 2015, 18:50

Re: Перевірити наявність реквізита в шапці

Повідомлення PetroP » 15 грудня 2021, 15:27

Немає такої можливості.
Вихід із ситуації для основної таблиці полягає у переборі циклом через спробу/виключення усіх реквізитів методом rsMain.Fields.Item(Лч).Name.
З таблицями - трохи важче. Бо може бути ситуація, коли немає таблиці 2, але є 3. Тож можна до нескінченності перебирати таблиці.

Inkognito
Повідомлень: 1067
З нами з: 14 січня 2012, 14:26

Re: Перевірити наявність реквізита в шапці

Повідомлення Inkognito » 15 грудня 2021, 16:59

Споідівався, що вже створили недокументований метод ;)
Логічно, що спеціалісти Медка, які займаються розвитком СОМ технології, прочитають і зрозуміють необхідність створити такий метод.
Якщо потрібно буде перевірити наявність декількох полів, реалізувати перебір датасету Х разів виглядає дивно.

Medoc Man
Повідомлень: 864
З нами з: 07 червня 2018, 14:28
Звідки: Kiev

Re: Перевірити наявність реквізита в шапці

Повідомлення Medoc Man » 16 грудня 2021, 17:39

Inkognito писав:
15 грудня 2021, 16:59
Споідівався, що вже створили недокументований метод ;)
Увы.
Я так понимаю подразумевается, что люди, которые используют СОМ для заполнения по полям отдельно, обычно знают, что им нужно заполнять, а что не нужно. Соответственно +- догадываются, есть там такое-то поле или его и не может быть.

Если часто возникает ситуация, когда неизвестно есть ли искомое поле или нет - вместо ожидания, пока сделают какой-то новый метод, можно, к примеру, взять топорный способ с Попыткой:
TryGetValue | Показать

Код: Виділити все

Function TryGetValue(dataSet, field)
	
	Try
		Return dataSet.FldVal(field);
	Except
		Message("Поле " + field + " не существует в шаблоне.");
	EndTry;
	
	Return Undefined;
	
EndFunction
Или усложнённый вариант с неким Кэшем шаблонов. Кэш шаблонов в данном случае некая Структура, где Ключ - это чаркод шаблона, а значение - XML-представление шаблона, полученное методом GetTemplate.
Идея в том, что перед началом работы с каким-то документом в M.E.Doc через СОМ, мы проверяем наличие структуры шаблона в этом Кэше и либо получаем эту структуру из Кэша (в виде XML-строки) либо получаем её через GetTemplate и сохраняем её Структуру (КэшШаблонов), если по ключу (ЧарКоду) ранее в кэше такого шаблона небыло.
| Показать

Код: Виділити все

Перем КэшШаблонов;

Процедура ПриОткрытии()
    КэшШаблонов = Новый Структура();
    // ...
КонецПроцедуры

Процедура ЧтотоТамДелаемСДокументом(...)

    // ...
    структураШаблона = "";
    Если НЕ КэшШаблонов.Свойство(КакойтоЧарКод, структураШаблона) Тогда
        структураШаблона = СокрЛП(App.GetPrimaryDocs().GetTemplate(7, КакойтоЧарКод));
        КэшШаблонов.Вставить(КакойтоЧарКод, структураШаблона);
    КонецЕсли;  
    // ...
    
    документ = ...OpenDocumentByCode(...).
    датаСет = документ.DataSets("MAIN");
    
    датаДокумента = TryGetValue(структураШаблона, датаСет, "DocDate")

КонецПроцедуры
Ну а далее просто обычным Найти ищем в XML-строке поле:
TryGetValue | Показать

Код: Виділити все

Function TryGetValue(template, dataSet, field)
	
	If Find(template, "field name=""" + Upper(field) + """") > 0 Then
		Return dataSet.FldVal(field);
	EndIf;
	
	Message("Поле " + Field + " не существует в шаблоне.");
	Return Undefined;
	
EndFunction
И в обратную сторону, если нужно проверить наличие поля перед заполнением:
TrySetValue | Показать

Код: Виділити все

Function TrySetValue(template, dataSet, field, value)
	
	If Find(template, field) > 0 Then
		dataSet.Fields.Item(field).Value = value;
	Else
		Message("Поле " + field + " не существует в шаблоне");
	EndIf;
	
EndFunction
Таким образом, через XML-структуру шаблона можно не только наличие поля проверять, но и, например, его тип (из аттрибута type).
Человек-волшебник
Людина-чарівник
Wizard man

Inkognito
Повідомлень: 1067
З нами з: 14 січня 2012, 14:26

Re: Перевірити наявність реквізита в шапці

Повідомлення Inkognito » 21 грудня 2021, 22:30

1) Такий код не працює. Медок як вилітав, так і вилітає.
Код | Показать
Function TryGetValue(dataSet, field)

Try
Return dataSet.FldVal(field);
Except
Message("Поле " + field + " не существует в шаблоне.");
EndTry;

Return Undefined;

EndFunction
2) "Или усложнённый вариант с неким Кэшем шаблонов."
Звичайно. Так зараз і робиться. Але це костиль, а не логічне вирішення проблеми. Дивно, що така логічна функція не реалізована.

Medoc Man
Повідомлень: 864
З нами з: 07 червня 2018, 14:28
Звідки: Kiev

Re: Перевірити наявність реквізита в шапці

Повідомлення Medoc Man » 23 грудня 2021, 13:03

Inkognito писав:
21 грудня 2021, 22:30
Медок як вилітав, так і вилітає.
У меня не вилітає)
Ну я имею в виду, что если впишу какое-то dataSet.FldVal("POLE_DLYA_PRIKOLA") оно конечно в 1С выкинет ошибку, но M.E.Doc остаётся работать.
Человек-волшебник
Людина-чарівник
Wizard man

Відповісти

Повернутись до “Модуль «Інтеграція»”