Автозаполнение нескольких реквизитов в форме документа
|
13.07.2017 15:29
Паршин Константин Александрович
|
Добрый день.(8.3, УФ) Возникла нужда заполнить несколько реквизитов (ИНН и НомерТелефона) в форме документа при выборе Контрагента. Само собой "КонтрагентПриИзменении" С задачей заполнить 1 ревизит, я справился, но как быть с двумя, к сожалению не доходит. Помогите разобраться, пожалуйста.
Если есть пара вариантов как это сделать, буду рад увидеть. Проблема с логикой программирования.
Вот пример того, как я заполнял один реквизит:
&НаКлиенте
Процедура КонтрагентПриИзменении(Элемент)
Объект.ИНН = ПолучитьИНН(Объект.Контрагент);
КонецПроцедуры
&НаСервереБезКонтекста
Функция ПолучитьИНН(Контрагент)
Возврат Контрагент.ИНН;
КонецФункции
|
Re: Автозаполнение нескольких реквизитов в форме документа
|
13.07.2017 16:56
Паршин Константин Александрович
|
Спасибо большое. Запишу для сеюя эту конструкцию в блокнот и буду разбираться.
Да, я делал обращение через точку на форме. Тогда всё подставлялось автоматом при выборе контрагнета без кода. Но тогда эти данные не выводились при выводе на печать, поэтому только программным путем.
|
Re: Автозаполнение нескольких реквизитов в форме документа
|
13.07.2017 17:04
Полетаев Александр
|
Ну так вывод на печать это другая задача... её всё равно нужно делать независимо от того где Вы расположите данные. При печати просто нужно брать ИНН и Телефон так же из Контрагента.
|
Re: Автозаполнение нескольких реквизитов в форме документа
|
13.07.2017 16:51
Полетаев Александр
|
Если редактирование ИНН и НомераТелефона не предполагается и нужны они только для отображения, то можно не добавляя реквизитов на форму и не заполняя их просто вывести нужные элементы формы "через точку" от Контрагента.
В противном случае (если всё же они нужны именно как реквизиты) -- Вы всё правильно делаете... и где один реквизит там и два, почему возникли сложности?
Например, через Структуру:
&НаКлиенте
Процедура КонтрагентПриИзменении(Элемент) СтруктураРеквизитов = ПолучитьРеквизиты(Объект.Контрагент);
Объект.ИНН = СтруктураРеквизитов.ИНН; Объект.НомерТелефона = СтруктураРеквизитов.НомерТелефона; КонецПроцедуры
&НаСервереБезКонтекста
Функция ПолучитьИНН(Контрагент)
Возврат Новый Структура("ИНН, НомерТелефона", Контрагент.ИНН, Контрагент.НомерТелефона);
КонецФункции
Более сложный и оптимальный способ получения значений нескольких реквизитов, который можно использовать везде и всегда -- написание универсальной функции (как в БСП), в которую передаётся ссылка и текстовый список реквизитов. Внутри функции строится простейший запрос с условием "ГДЕ Ссылка=&Ссылка" и выборкой _только тех реквизитов_, которые необходимы. И возврат их так же, через структуру.
|
Re: Автозаполнение нескольких реквизитов в форме документа
|
13.07.2017 17:40
Паршин Константин Александрович
|
Подобный способ можо использовать в такой же ситуации, если заполняем реквизиты ТЧ? Или там структоруй никак?
Я один реквизит ТЧ заполнял вот так:
&НаКлиентеПроцедура ВыполненныеРаботыВидРаботыПриИзменении(Элемент)
ТекСтрока = Элементы.ВыполненныеРаботы.ТекущиеДанные;
ТекСтрока.Стоимость = ПолучитьСтоимость(ТекСтрока.ВидРаботы);
КонецПроцедуры
&НаСервереБезКонтекстаФункция ПолучитьСтоимость(ВидРаботы)
Возврат ВидРаботы.Стоимость;
КонецФункции
|
Re: Автозаполнение нескольких реквизитов в форме документа
|
14.07.2017 08:54
Колосов Юрий Константинович
|
Только лучше получать данные запросом.
|
Re: Автозаполнение нескольких реквизитов в форме документа
|
14.07.2017 12:23
Толокнов Алексей
|
Для реквизитов 1 объекта БД не принципиально.
|
Re: Автозаполнение нескольких реквизитов в форме документа
|
14.07.2017 14:37
Колосов Юрий Константинович
|
Запросом прочитаем только то, что нужно, а через точку – все реквизиты и все ТЧ объекта. А ведь там еще может оказаться реквизит с типом ХранилищеЗначений с какой-нибудь картинкой на несколько мегабайт.
|
Re: Автозаполнение нескольких реквизитов в форме документа
|
14.07.2017 14:57
Толокнов Алексей
|
Платформа и так запросом обратится, особенно в SQL. А что касается "ХранилищаЗначений", то пока вы принудительно от туда читать не начнёте, платформа из БД это читать не будет.
Запрос хорош для выборок, а не для чтения одиночных записей.
|
Re: Автозаполнение нескольких реквизитов в форме документа
|
14.07.2017 15:20
Полетаев Александр
|
Обращение к реквизиту ссылки через точку считывает и кэширует все реквизиты этой ссылки (на всякий случай). Конечно, это будет запрос в SQL... но тем не менее, ради получения одного-единственного реквизита будет считан весь объект со всеми его табличными частями.
Можете проверить профайлером (типа "SELECTT2._IDRRef,T2._Version,T2._Marked,T2._PredefinedID,T2._ParentIDRRef,T2._Folder,T2._Code,T2._Description,T2._Fld29,T2._Fld54,T2._Fld55,T2._Fld56,T2._Fld57,0 AS SDBL_IDENTITYFROM dbo._Reference24 T2WHERE T2._IDRRef = @P1" и потом ещё запросы по табличным частям).
А запрос "выбрать спр.рекв1 из справочники.справочник1 как спр где спр.ссылка=&ссылка" трансформируется в простой SQL-запросик типа "SELECTT1._Fld29FROM dbo._Reference24 T1WHERE (T1._IDRRef = @P1)"
|
Re: Автозаполнение нескольких реквизитов в форме документа
|
14.07.2017 15:37
Толокнов Алексей
|
> Можете проверить профайлером Пока поверю на слово, потом как нибудь проверю. По скорости разница просто не чувствуется, потому не парюсь пока по такому.
|
Re: Автозаполнение нескольких реквизитов в форме документа
|
14.07.2017 18:12
Колосов Юрий Константинович
|
Вот здесь про это можно почитать, если интересно: https://its.1c.ru/db/metod8dev/content/2717/hdoc
|
Re: Автозаполнение нескольких реквизитов в форме документа
|
14.07.2017 12:35
Паршин Константин Александрович
|
Хотелось бы увидеть пример получения неск реквизитов в ТЧ( при изменении) с помощью запроса.
Могли бы написать? Пусть будут любые переменные.
|
Re: Автозаполнение нескольких реквизитов в форме документа
|
14.07.2017 13:23
Толокнов Алексей
|
> при изменении В 1С запросы поддерживают только чтение, запросы UPDATE и DELETE не поддерживаются.
|
Re: Автозаполнение нескольких реквизитов в форме документа
|
14.07.2017 13:34
Паршин Константин Александрович
|
Я знаю.
Запрос использовать необходимо для получение реквизитов, чтобы их автозаполнить в дальнейшем.
|
Re: Автозаполнение нескольких реквизитов в форме документа
|
14.07.2017 14:26
Колосов Юрий Константинович
|
Функция ПолучитьДанныеКонтрагента(Знач СсылкаНаКонтрагента) Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ |Контрагенты.ИНН, |Контрагенты.КПП, |Контрагенты.НаименованиеПолное |ИЗ |Справочник.Контрагенты КАК Контрагенты |ГДЕ |Контрагенты.Ссылка = &Ссылка"; Запрос.УстановитьПараметр("Ссылка", СсылкаНаКонтрагента); Выборка = Запрос.Выполнить().Выбрать(); ДанныеКонтрагента = Новый Структура; Выборка.Следующий(); ДанныеКонтрагента.Вставить("ИНН", Выборка.ИНН); ДанныеКонтрагента.Вставить("КПП", Выборка.КПП); ДанныеКонтрагента.Вставить("НаименованиеПолное", Выборка.НаименованиеПолное); Возврат ДанныеКонтрагента; КонецФункции;
|
Re: Автозаполнение нескольких реквизитов в форме документа
|
14.07.2017 14:39
Паршин Константин Александрович
|
|
Re: Автозаполнение нескольких реквизитов в форме документа
|
14.07.2017 14:29
Толокнов Алексей
|
> Функция ПолучитьДанныеКонтрагента(Знач СсылкаНаКонтрагента) В данном случае я бы так делать не стал бы.
|
Re: Автозаполнение нескольких реквизитов в форме документа
|
14.07.2017 14:38
Колосов Юрий Константинович
|
|
Re: Автозаполнение нескольких реквизитов в форме документа
|
14.07.2017 14:52
Толокнов Алексей
|
Процедура НекаяПроцедура()
йй = 1;
Сообщить("1: "+йй);
Процедура1(йй);
Сообщить("2: "+йй);
Процедура2(йй);
Сообщить("3: "+йй);
КонецПроцедуры
Процедура Процедура1(йй)
йй=йй+1;
КонецПроцедуры
Процедура Процедура2(Знач йй)
йй=йй+1;
КонецПроцедуры
Когда вы используете для описания параметров Процедуры/Функции ключевое слово "Знач" система передаёт туда не указатель на ячейку памяти, где расположенна переменная, а саму переменную, или по рабоче-крестьянски её копию. Что не всегда хорошо, так как требует выделение дополнительной памяти. Не стоит использовать это в функциях, где вы и так не собираетесь менять значение этой переменной.
|
Re: Автозаполнение нескольких реквизитов в форме документа
|
14.07.2017 18:19
Колосов Юрий Константинович
|
На сколько я знаю, при передаче параметра по ссылке с клиента на сервер переданный параметр после окончания процедуры поедет обратно на клиент (ведь раз мы передаём что-то по ссылке подразумевается, что это что-то должно потом вернуться в точку вызова). Если это будет не ссылка, а какой-то большой объект, то это будет не оптимально.
|
Re: Автозаполнение нескольких реквизитов в форме документа
|
14.07.2017 20:49
Толокнов Алексей
|
Там сама логика передачи разная.
В C++ или Pascal передача переменных в функцию идет через запихивания в стек указателей на память(32 бита) где записанны переменные, но в случае передачи параметра через Var(аналог Знач) сам параметр запихивается в стек.
Я не думаю что разработчики платформы 1С сильно что то поменяли в этом алгоритме, они всё таки C++ или C# изучали.
|
Re: Автозаполнение нескольких реквизитов в форме документа
|
14.07.2017 14:22
Толокнов Алексей
|
Примерно так:
Функция ПолучитьРеквизитыСправочника(СсылкаНаЭлементСправочника)
Если НЕ Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч(СсылкаНаЭлементСправочника)) Тогда
Возврат Неопределено;
КонецЕсли;
ИмяСправочника = СсылкаНаЭлементСправочника.Метаданные().Имя;
СтруктураВозврата = Новый Структура;
Для каждого МетРеквизит Из СсылкаНаЭлементСправочника.Метаданные().Реквизиты Цикл
СтруктураВозврата.Вставить(МетРеквизит.Имя);
КонецЦикла;
ТекстЗапроса = "Выбрать * Из Справочник."+ИмяСправочника+" Где Ссылка=&Ссылка";
Запрос = Новый Запрос(ТекстЗапроса);
Запрос.УстановитьПараметр("Ссылка", СсылкаНаЭлементСправочника);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
ЗаполнитьЗначенияСвойств(СтруктураВозврата, Выборка);
Возврат СтруктураВозврата;
Иначе
Возврат Неопределено;
КонецЕсли;
КонецФункции
Честно скажу, код не проверял.
|
Re: Автозаполнение нескольких реквизитов в форме документа
|
14.07.2017 14:38
Паршин Константин Александрович
|
Спасибо большое.
Сохраню себе. Но, кажется, сложновато для меня пока для такой нехитрой операции. Буду делать через структуру.
|
Re: Автозаполнение нескольких реквизитов в форме документа
|
14.07.2017 12:07
Паршин Константин Александрович
|
Никак не доходит, как это сделать.
Приведете пример какой-нибудь?
Чтобы я понимал как это сделать.
|
Re: Автозаполнение нескольких реквизитов в форме документа
|
13.07.2017 16:54
Толокнов Алексей
|
Ну и зачем новичку давать полностью готовое решение? Ему учиться надо.
|
Re: Автозаполнение нескольких реквизитов в форме документа
|
13.07.2017 17:03
Полетаев Александр
|
Вы тоже дали готовое решение -- "выполнить последовательно 2 операции" :) я тоже мог бы спросить -- зачем новичку давать готовое решение которое научит его такому плохому стилю программирования?
Я как минимум дал ему выбор аж из трёх вариантов... не считая Вашего четвёртого.
|
Re: Автозаполнение нескольких реквизитов в форме документа
|
13.07.2017 17:10
Толокнов Алексей
|
Я код не хотел давать :)
> зачем новичку давать готовое решение которое научит его такому плохому стилю программирования? В чем то вы конечно правы, подсказка была не самая эстетически правильная. Но шишки надо набить свои.
|
Re: Автозаполнение нескольких реквизитов в форме документа
|
13.07.2017 16:38
Толокнов Алексей
|
> С задачей заполнить 1 ревизит, я справился, но как быть с двумя, Выполнить последовательно 2 операции, сначала первый потом второй.
|
Re: Автозаполнение нескольких реквизитов в форме документа
|
13.07.2017 16:47
Паршин Константин Александрович
|
Т.Е. Нужно добавить еще одну процедуру и функцию?
|
Re: Автозаполнение нескольких реквизитов в форме документа
|
13.07.2017 16:53
Толокнов Алексей
|
Хотите добавте ещё 1 функцию, хотите переделайте функцию что бы она 2 значения возвращала(масси или структура), хотите переделайте серверную функцию в процедуру и в ней заполняйте оба реквизита. Вариантов много, выбирать вам как автору :)
|