Получить значение из поля выбора 1с
Использование отбора:
Функционал, который используется для интерактивного отбора в списках, можно использовать и для отбора программным способом.
Для этого нужно для события НачалоВыбора соответствующего поля ввода определить процедуру обработки и внутри процедуры программно устанавить отбор для списка.
Далее следует пример процедуры обработки события НачалоВыбора для поля ввода СтатьяПДР. Реквизит (и поле ввода, соответственно) СтатьяПДР имеет тип СправочникСсылка.ПрочиеДоходыИРасходы. Для списка справочника «Прочие доходы и расходы» устанавливается отбор по реквизиту «Вид прочих доходов и расходов» со значением «Прочие внереализационные доходы (расходы)».
Код 1C v 8.х
Обратите внимание на строку кода:
Код 1C v 8.х
Она закрывает доступ к настройке отбора «Вид прочих доходов и расходов». Таким образом, пользователь не может отключить заданный программно отбор и имеет возможность сделать выбор значения только из ограниченного списка.
Внутри процедуры обработки события НачалоВыбора параметру СтандартнаяОбработка нужно обязательно присвоить значение Ложь. В противном случае будет открыт и ограниченный список, и стандартный список, а это, конечно, не входит в наши планы.
В следующем примере для поля ввода СчетДт типа ПланСчетовСсылка.Хозрасчетный устанавливается отбор в виде списка счетов. Список счетов предварительно формируется с помощью запроса.
Использование выбора из списка:
Выбор значения Перечисления обычно осуществляется из маленького списка. Но даже если включить выбор из формы (это делается с помощью свойства «Быстрый выбор» поля ввода), функционал отбора для перечислений все равно неприменим.
В таком случае подходящий способ ограничения списка выбора - использование метода формы ВыбратьИзСписка. Аналогично первому способу, необходимо определить процедуру обработки события НачалоВыбора для поля ввода значения. В следующем примере для поля ввода ВидПДР типа ПеречислениеСсылка.ВидыПрочихДоходовИРасходов программно устанавливается ограниченный список выбора.
Результат работы процедуры показан на рисунке. Метод ВыбратьИзСписка открывает маленький список с набором значений, переданных в процедуру в первом параметре (в примере - список значений ВидыПДР).
Пример ограничения списка выбора для перечисления в 1С 8
При выборе ссылочного значения в поле ввода иногда возникает необходимость специальным образом обработать выбирамемое значение.
Например, в документе, нужно выбрать поставщика. Но нужно вмешаться в процесс выбора значения и кроме ссылки на поставщика получить еще и другую информацию о поставщике. Например, его полное наименование и ИНН, которые являются реквизитами поставщика.
Для того, чтобы вмешаться в процесс выбора значения используется событие ОбработкаВыбора элемента формы Поле. Это событие поставляется расширением поля ввода. Обработчик этого события имеет такой синтаксис:
Во втором параметре (ВыбранноеЗначение) платформа передает в обработчик то значение, которое выбрал пользователь. В данном случае это будет ссылка на поставщика.
Но проблема заключается в том, что обработчик ОбработкаВыбора исполняется на клиенте, то есть объявление процедуры выглядит так:
А на клиенте возможности ссылки очень сильно ограничены. В частности, от нее нельзя через точку получить значения реквизитов.
Поэтому для того, чтобы в этой ситуации получить значения реквизитов ссылки, нужно из этого обработчика вызвать серверную функцию и в ней получить нужные реквизиты. Например так:
При этом следует иметь ввиду два момента:
- Во-первых, для получения реквизитов используется неконтекстный серверный вызов (&НаСервереБезКонтекста). Это важно, т.к. в этом обработчике нельзя использовать контекстные серверные вызовы (&НаСервере).
- Во-вторых, любое обращение к серверу требует дополнительных ресурсов системы и может замедлять работу пользователя, особенно в случае подключения по низкоскоростному каналу связи. Поэтому нужно прежде всего внимательно оценить, а так ли необходимо в этом месте получать реквизиты ссылки или можно обойтись без этого? И если нужно получать несколько реквизитов и при этом используется какой-то сложный алгоритм – нужно постараться реализовать его так, чтобы все необходимые данные получить за один серверный вызов, вернуть их на клиента и на клиенте только поместить их в нужные поля формы, не проводя каких-то сложных вычислений.
Подробнее об использовании метода ОбработкаВыбора можно прочитать в синтакс-помощнике: Интерфейс (управляемый) - Поле формы - Расширение поля ввода - События:
Список значений — это программная коллекция (объект встроенного языка), содержащая пронумерованную последовательность элементов. Каждому элементу присваивается последовательный целочисленный номер — индекс, начинающийся с нуля. По индексу можно получить или установить элемент списка значений.
Элемент списка значений
Каждый элемент списка является программным объектом ЭлементСпискаЗначений встроенного языка и содержит следующие свойства:
- Значение (Произвольный тип) — хранимое значение произвольного типа
- Представление (Строка) — представление элемента списка для пользователя
- Пометка (Булево) — значение пометки элемента в списке
- Картинка (Картинка) — картинка элемента списка для пользователя
Создание списка значений
Создание пустого списка значений выполняется с помощью оператора Новый:
Для добавления элементов в список значений используется одноименный метод СписокЗначений.Добавить():
Каждый новый элемент помещается в конец списка. Для доступа к отдельным элементам списка значений применяется операция разыменования: указывается имя переменной, объявленной как список значений, а затем, в квадратных скобках, указывается индекс элемента. Свойства полученного элемента можно использовать как слева от оператора присваивания:
Так и справа: в выражениях и в качестве параметров процедур и функций:
Границы списка значений
Как было сказано выше, левая граница списка значений постоянна и всегда равно нулю (0). Верхняя граница напрямую связана с количеством элементов в списке значений. Получить ее можно с использованием метода СписокЗначений.Количество() с последующим вычитанием 1.
Давайте рассмотрим распространенные операции со списком значений.
Перебор элементов списка значений
Для перебора (обхода) всех элементов списка значений обычно используется оператор цикла Для :
Либо оператор цикла Для Каждого :
Второй способ больше подходит для ситуации, когда нужно только последовательно перебрать все значения списка. Его использование повышает «читабельность кода».
Поиск в списке значений
Для поиска значений в списке предназначен метод СписокЗначений.НайтиПоЗначению(). Он возвращает найденный элемент списка значений, либо Неопределено , если указанного значения в списке нет.
Сортировка списка значений
Сортировка элементов в списке значений может производиться двумя способами:
Получить значение из текущей ячейки списка в УФ - оказывается, не так-то просто. Особенно если хочется сделать универсальное решение. Предлагаю свой, достаточно общий способ. И до кучи - быстрый отбор по значению текущей колонки.
Как это было просто в обычном интерфейсе: ЭлементыФормы..ТекущиеДанные[ЭлементыФормы..ТекущаяКолонка.Имя]. И как это, оказывается, нетривиально для списков в УФ. Особенно в общем случае, который я и рассматривал, работая с ТекущимиДанными как с ДаннымиФормыбезотносительно их происхождения и наполнения.
Как известно, колонки динамического списка могут являться разыменованиями колонок-полей основной таблицы/запроса, причём они могут быть добавлены как в Конфигураторе, так и пользователем либо программистом в режиме Предприятие. И вот тут 1С немного "поленились": если для "штатно" объявленных полей таблицы/запроса ещё работает ТекущиеДанные[ИмяКолонки] и для них ТекущиеДанные.Свойство(ИмяКолонки) возвращает истину, то вот уже полей, добавленных в Конфигураторе как разыменование, хоть на 1 шаг вперёд, нет возможности получить их значение. Видеть - видим, программно не получаем. Но это ещё терпимо, т.к. для таких полей есть свойство их реквизита ПутьКДанным, по которому можно, исходя из "штатно" объявленных полей, вытащить значение.
Дальше интереснее. Поля, добавленные в режиме "Предприятие" как разыменование имевшихся (и неважно, штатно-объявленных основных полей или разыменованных в конфигураторе), - эти поля вообще никак не ущучить. Для них свойство "ПутьКДанным" вообще не поддерживается, не говоря уж о ТекущиеДанные[ИмяКолонки]. Видеть - видим, общий отбор обычным образом поставить можем, а получить видимое невооружённым глазом значение ячейки программно - нет.
Да, у таких добавленных разыменованных полей есть имена. Говорящие имена. И на этом были основаны пара решений, которые на ИС появились ещё в лохматые времена. НО: у них есть один недостаток. Как известно, работая с путями к данным, которые надо преобразовать в валидные имена 1С, любая СКД в системном представлении заменяет точки на знак подчёркивания. И вот теперь у нас есть развлечение: мы знаем имя поля, но в общем виде мы не гарантированы, что разработчик не употреблял знак подчёркивания в своих целях, а значит, нам придётся отличать, который из знаков подчёркивания в имени поля, например, вида Главное_Событие_Тип_События_Код задан разработчиком, а который подсунут СКД при преобразовании пути. СКД динамического списка тут не исключение.
Заметим также, что СКД ещё и стандартные реквизиты именует латиницей (DeletionMark, а не ПометкаУдаления), притом что локализованная 1С при переборе коллекции метаданных СтандартныеРеквизиты в их свойстве "Имя" возвращает-таки русскоязычное написание.
Ничего не скажу плохого про другие варианты решений, но проблему подчёркиваний там, насколько видел, не решали. Мне пришлось решить. Выкладываю прямо тут. Некоторая странность функции ПолучитьЗначениеТекущейЯчейки объясняется желанием уконтрапупить всё в одну функцию, чтобы удобнее было таскать между модулями. При желании функцию ПолучитьЭлементыИРеквизитыДинамическогоСписка также можно засунуть внутрь, указав соответствующий РежимВызова. Словом, место для извращений есть.
Если рРежим = "Получение" Тогда
текдан = рПараметры . ТекущиеДанные ;
рИмяПоля = рПараметры . ИмяПоля ; // имя текущей колонки
ЭиР =?( рПараметры . Свойство ( "ЭлементыИРеквизиты" ), рПараметры . ЭлементыИРеквизиты ,Неопределено);
//
Если ЭиР =Неопределено Тогда
ЭиР = ПолучитьЭлементыИРеквизитыДинамическогоСписка ( ЭтаФорма , рПараметры . ИмяЭлементаИРеквизитаСписка );
рПараметры . Вставить ( "ЭлементыИРеквизиты" , ЭиР );
КонецЕсли;
//
// здесь же, если надо, преобразование англоязычных служебных полей в русскую нотацию (вместо _Code делаем _Код)
Если текдан . Свойство ( рИмяПоля ) Тогда // штатно объявленное поле 1-го уровня
рЗначение = текдан [ рИмяПоля ];
рПараметры . Вставить ( "ПутьКДанным" , рИмяПоля );
Иначе // разыменованное как-либо поле
// ищем среди сведений об элементах и реквизитах
рНужное =Неопределено;
Для каждого эл Из ЭиР Цикл
Если Лев ( рИмяПоля , СтрДлина ( СокрЛП ( эл . Имя )))= СокрЛП ( эл . Имя ) Тогда
рНужное = эл ; Прервать;
КонецЕсли;
КонецЦикла;
Если рНужное <>Неопределено Тогда // скорее всего, разыменованное как-либо
Если СокрЛП ( рНужное . Имя )= рИмяПоля Тогда // точное совпадение - значит, разыменование было в конфигураторе
Выполнить( "рЗначение=текдан." + СокрЛП ( рНужное . Путь ));
рПараметры . Вставить ( "ПутьКДанным" , рНужное . Путь );
Иначе // скорее всего, разыменованное от разыменованного, в т.ч. добавленное динамически
// первый шаг надо делать от имеющихся полей текдан, и они возможны любые, поэтому привлекаем ЭиР,
// а далее возможны лишь их реквизиты, т.е. простые разыменования, и там вся задача лишь в преобразовании
// имеющегося сейчас пути (только знаки подчёркивания) в путь правильного формата, через точку (где надо).
//
рПараметрыДалее =Новый Структура ;
рПараметрыДалее . Вставить ( "РежимВызова" , "Разыменование" );
рПараметрыДалее . Вставить ( "ИмяЭлементаИРеквизитаСписка" , рПараметры . ИмяЭлементаИРеквизитаСписка );
рПараметрыДалее . Вставить ( "ИмяПуть" , рИмяПоля );
рПараметрыДалее . Вставить ( "ОсталосьРазобрать" , рИмяПоля );
рПараметрыДалее . Вставить ( "ИмяИсходногоПоля" , СокрЛП ( рНужное . Имя ));
рПараметрыДалее . Вставить ( "ОписТиповИсходногоПоля" , рНужное . ТипЗначения );
ПолучитьЗначениеТекущейЯчейки ( рПараметрыДалее );
рИмяПуть = рПараметрыДалее . ИмяПуть ;
//
рПараметрыДалее =Новый Структура ( "ТекущиеДанные,ИмяПоля,ЭлементыИРеквизиты" , текдан , СокрЛП ( рНужное . Имя ), ЭиР );
рЗначениеИсхПоля = ПолучитьЗначениеТекущейЯчейки ( рПараметрыДалее );
рПутьБезИсходного = СтрЗаменить ( рИмяПуть , СокрЛП ( рНужное . Имя )+ "." , "" );
Выполнить( "рЗначение=рЗначениеИсхПоля." + СокрЛП ( рПутьБезИсходного ));
рПараметры . Вставить ( "ПутьКДанным" , рИмяПуть );
КонецЕсли;
Иначе
рЗначение =Неопределено; // такого имени не нашли по началу строки ни одного из имён элементов (некая неучтённая ситуация)
рПараметры . Вставить ( "ПутьКДанным" , "" );
КонецЕсли;
КонецЕсли;
//
Возврат рЗначение ;
Что ещё из интересного успел пронаблюдать:
1. В настройке формы поля с подчёркиванием и без штатных представлений ооочень забавно выглядят. Посмотрите сами ))
2. При изменении данных объявленные в конфигураторе обновляются, а добавленные динамически в 1С - нет. Приходится переоткрывать форму. Или это у меня релиз такой (19.83), или лыжи не совсем едут.
3. Несмотря на то, что стандартные реквизиты в служебных именах СКД списка даёт латиницей, в диалоге настройки списка установленные исходя из англоязычных термов отборы представлены по-русски.
4. Если разыменованное поле имеет тип Булево, но путь разыменования прерван пустым значением (т.е. до конечного значения просто нельзя дойти), показ псевдозначения поля в этой колонке всё равно будет, равный "нет", но при отборе по "Нет" он эту строку в удовлетворяющие отбору не включит. Спецэффект, вызывающий недоумение пользователей.
И "до кучи" предлагаю процедуру установки "быстрого отбора" по значению текущей колонки. Да, есть отборы, вызываемые через "Настроить список", да, есть поиск с множественным отображением, но привычка пользователя - страшная штука, да и нажатий меньше.
рПараметры =Новый Структура ( "ТекущиеДанные,ИмяПоля" , текдан , теккол . Имя );
рПараметры . Вставить ( "ИмяЭлементаИРеквизитаСписка" , СокрЛП ( рИмяСписка ));
рЗначение = ПолучитьЗначениеТекущейЯчейки ( рПараметры );
Если рЗначение =Неопределено Тогда
Предупреждение ( "Отбор по текущей колонке невозможен, нельзя получить значение отбора!" ); Возврат
КонецЕсли;
мстро = ОбщегоНазначения . РазложитьСтрокуВМассивПодстрок ( рПараметры . ПутьКДанным , "." );
рИсходноеПоле = СокрЛП ( мстро . Получить ( 0 ));
ЭиР = рПараметры . ЭлементыИРеквизиты ;
рНачалоПути = "" ;
Для каждого эл Из ЭиР Цикл
Если СокрЛП ( эл . Имя )= рИсходноеПоле Тогда
рНачалоПути = СокрЛП ( эл . Путь ); Прервать;
КонецЕсли;
КонецЦикла;
Если ПустаяСтрока ( рНачалоПути ) Тогда
Предупреждение ( "Отбор по текущей колонке невозможен, нельзя определить путь отбора!" ); Возврат
КонецЕсли;
рИтоговыйПуть = СтрЗаменить ( рПараметры . ПутьКДанным , рИсходноеПоле + "." , рНачалоПути + "." );
Список значений в 1С 8.3 — это объект, позволяющий строить динамические наборы значений и манипулировать ими.
Визуально можно представить как таблицу из четырёх колонок:
- значение,
- картинка,
- пометка,
- представление.
Список значений может быть наполнен значениями любых типов. Значения характеризуются позицией в списке (индексом).
Рассмотрим работу с объектом на примерах:
Создание объекта СписокЗначений
Добавить элемент в список значений
Удалить элемент списка значений
Вставить элемент в список значений
Установить/снять пометки у всех элементов
Найти в списке значений
Узнать индекс элемента с известным значением
Отсортировать список значений
Сдвинуть элемент списка значений
Создать копию списка значений
Получить количество элементов списка значений
Перебор элементов списка значений
Загрузить/выгрузить в массив
Удалить все элементы из списка значений
Интерактивный выбор одного элемента из списка на форме
Модальный и немодальный режим. Универсальный способ:
Интерактивная отметка значений из списка на форме
Модальный и немодальный режим. Универсальный способ:
Преобразования таблицы значений в список значений
Поддержите нас, расскажите друзьям!
СПРОСИТЕ в комментариях!
При использовании данного сайта, вы подтверждаете свое согласие на использование файлов cookie в соответствии с настоящим уведомлением в отношении данного типа файлов. Если вы не согласны с тем, чтобы мы использовали данный тип файлов, то вы должны соответствующим образом установить настройки вашего браузера или не использовать сайт.
Отправляя любую форму на сайте, вы соглашаетесь с политикой конфиденциальности данного сайта.
Читайте также: