1с как обратиться к программно созданному реквизиту формы

Как обратиться к реквизиту формы в УФ

Я
   DenisSS

09.04.18 — 08:37

Есть реквизит формы, созданный программно. Как обратиться к этому реквизиты, например, в ПослеЗаписиНаСервере? При отладке значение этого реквизита доступно, но такая строка естественно вызывает ошибку:

Сообщить(РеквизитСозданныйПрограммно)

Переменная не определена (РеквизитСозданныйПрограммно)

  

Партнерская программа EFSOL Oblako

   DmitrO

1 — 09.04.18 — 08:45

ЭтотОбъект[«ИмяРеквизита»]

   DenisSS

2 — 09.04.18 — 08:54

Спасибо работает, но так тоже работает, не ругается: ЭтаФорма.ИмяРеквизита

   Lexey_

3 — 09.04.18 — 08:58

(2) ЭтотОбъект = ЭтаФорма

   DmitrO

4 — 09.04.18 — 10:01

1.ЭтаФорма — оставлено для совместимости.

2.С какого-то релиза (не помню) платформа явно блокирует исключением обращение к программным реквизитам через точку (это уже для совместимости на будущее). Об этом видел официальное заявление в документации.

   ildary

5 — 09.04.18 — 10:15

(4) извините что вмешиваюсь, то есть на сегодня самый правильный способ — это ЭтотОбъект[«ИмяРеквизита»], а ЭтаФорма.ИмяРеквизита — не рекомендуется по причине устаревания?

   Cyberhawk

6 — 09.04.18 — 10:17

(5) Правильнее всего для чтения значения программно созданного реквизита создавать структуру-зонд + ЗаполнитьЗначенияСвойств (т.к. реквизит может быть и удален)

   Cyberhawk

7 — 09.04.18 — 10:24

(ну а для получения реквизита формы как объекта встроенного языка — без точки и без «ЭтаФорма», о чем сказано выше)

   ildary

8 — 09.04.18 — 10:25

(6) извините, я правильно понял: структура-зонд — это структура с именами как у формы, которую (структуру) будем заполнять через ЗаполнитьЗначенияСвойств()? Выглядит рабоче, но вот ради одного поля гонять столько данных — не очень рационально.

   Cyberhawk

9 — 09.04.18 — 10:27

(8) Это структура с именем ключа, совпадающим с именем реквизита, о существовании которого заранее неизвестно (он мог быть уже и удален, т.к. создан программно и для таких это возможно).

Насчет «гонять столько данных» — во-первых, сколько «столько»? А во-вторых это, видимо, единственный способ получить значение без оборачивания в попытку.

  

hhhh

10 — 09.04.18 — 10:28

(8) зачем гонять? в ЗаполнитьЗначенияСвойств() задаете список реквизитов в 3м параметре. Может вы там один реквизит напишете.

Закон Брукера: Даже маленькая практика стоит большой теории.

  1. Добрый день.
    Программно создаю реквизит и элемент формы, после ввода значений хочу, записать введенные данные в регистр сведений, не пойму как это сделать.
    При нажатии на кнопку формы справочника «добавить реквизит» открывается ПВХ, там ввожу наименование и при записи передаю значения на форму справочника. На форме справочника создается реквизит с указанным в пвх наименованием. Далее при записи элемента справочника мне надо записать эти данные в РС. Не могу понять как взять значение созданного реквизита? Попробовал создать реквизит «РеквизитДляРС» не программно, а потом в него внести, ничего не получается.
    Код модуля формы элемента справочника:

    &НаКлиенте
    Процедура ДобавитьРеквизит(Команда)
        Закрытие = Новый ОписаниеОповещения("ОписаниеЗакрытия",ЭтаФорма);
        ОткрытьФорму("ПланВидовХарактеристик.СвойстваКошельков.Форма.ФормаЭлемента",,ЭтаФорма,,,,Закрытие);
    КонецПроцедуры
    
    &НаСервере
    Процедура ОписаниеЗакрытия(Результат,Параметры) экспорт
        Если ТипЗнч(Результат) = Тип("Структура") Тогда
            НовыеРеквизиты = Новый Массив;
            НовыйРеквизит = Новый РеквизитФормы(Результат.Имя,Результат.Тип,,,Истина);
            НовыеРеквизиты.Добавить(НовыйРеквизит);
            ИзменитьРеквизиты (НовыеРеквизиты);  
      
            Элемент = Элементы.Добавить(Результат.Имя,Тип("ПолеФормы"),ЭтаФорма);
            Элемент.Вид = ВидПоляФормы.ПолеВвода;
            Элемент.ПутьКДанным = Результат.Имя;   
            РеквизитДляРС = Новый Структура;
            РеквизитДляРС.Вставить("Имя", Результат.Имя);
        КонецЕсли;
    КонецПроцедуры    
    
    &НаКлиенте
    Процедура ПослеЗаписи(ПараметрыЗаписи)
            РеквизитДляРС.Вставить ("Тип",????); // Вот тут вместо ???? как мне обратиться к реквизиту?
            ЗаписьВРегистр();      
    КонецПроцедуры
    
    &НаСервере
    Процедура ЗаписьВРегистр()
            МенеджерЗаписи = РегистрыСведений.ЗначенияСвойствКошельков.СоздатьМенеджерЗаписи();
            МенеджерЗаписи.Кошелек = Объект.Ссылка;
            МенеджерЗаписи.ВидСвойства = РеквизитДляРС.Имя;
            МенеджерЗаписи.Значение = РеквизитДляРС.Тип;
            МенеджерЗаписи.Записать();
    КонецПроцедуры
    

    Код модуля формы элемента ПВХ:

    &НаКлиенте
    Процедура ПослеЗаписи(ПараметрыЗаписи)
        ВыбранноеЗначение = Новый Структура;
        ВыбранноеЗначение.Вставить("Имя",Объект.Ссылка);
        ВыбранноеЗначение.Вставить("Тип",Объект.ТипЗначения);
        ОповеститьОВыборе(ВыбранноеЗначение);
    КонецПроцедуры
    

    В процедуре формы справочника послезаписи как мне обратиться к реквизиту вместо «????» или я вообще не правильно делаю?

    Последнее редактирование: 19 июн 2017

  2. nomad_irk

    Offline

    nomad_irk
    Гуру в 1С

    Регистрация:
    20 окт 2008
    Сообщения:
    9.889
    Симпатии:
    1.029
    Баллы:
    204

  3. ЭтаФорма.НовыйРеквизит пробовал, поле объекта не обнаружено «НовыйРеквизит»

    — Объединение сообщений, 19 июн 2017

    Может я просто пишу не там?


  4. 1с-ник

    Offline

    1с-ник
    Профессионал в 1С
    Заблокирован

    Регистрация:
    5 окт 2014
    Сообщения:
    998
    Симпатии:
    164
    Баллы:
    104

    Как создавали так и обращайтесь :)
    Только вот область видимости переменной «Результат» — в пределах процедуры ОписаниеЗакрытия().
    Т.е. либо запоминайте имя реквизита, либо делайте перебор всех реквизитов формы (вряд ли у программно-созданного имеется признак, хотя можно к имени указывать префикс «СозданныйПрограммно_»), наверняка последний из них — как раз ваш.

  5. Вот в этом то и проблема. Если бы я сразу знал имя реквизита (например: цвет), то я бы сразу писал этаформа.цвет, а проблема в том, что название реквизита приходит из ПВХ, поэтому помимо этой процедуры, не знаю как обратиться к нему

    — Объединение сообщений, 19 июн 2017

    А через результат.Имя, я же получу имя реквизита, а не его значение?

  6. а как мне его запомнить, чтобы передать потом в другую процедуру? В отладчике открываю ЭтаФорма, вижу созданный реквизит и значение, а как вытащить его не знаю. Поэтому я и создавал реквизит не программно, в который пытался записать имя реквизита и потом уже пробовал обратиться через него, но ничего не вышло

    РеквизитДляРС = Новый Структура;
            РеквизитДляРС.Вставить("Имя", Результат.Имя); 
        МенеджерЗаписи.Значение = ЭтаФорма.РеквизитДляРС;
    

    Получаю только имя, как всегда


  7. 1с-ник

    Offline

    1с-ник
    Профессионал в 1С
    Заблокирован

    Регистрация:
    5 окт 2014
    Сообщения:
    998
    Симпатии:
    164
    Баллы:
    104

    Объект[ИмяРеквизита] — его значение;
    Элементы[ИмяРеквизита] — его элемент формы, поле ввода.
    У вас могут быть несколько добавленных реквизитов? И что вы с ними собираетесь делать?
    Ууу, совсем все плохо.

  8. Я программирую меньше месяца, конечно еще все плохо :(, да может быть несколько добавленных реквизитов. Просто надо чтоб при записи элемента справочника все созданные реквизиты с их значениями записывались в независимый регистр сведений. (пример: Справочник Кошельки, , создаю кошелек1, нажимаю добавить реквизит, открывается ПВХ, создаю характеристику «Тип карты», нажимаю записать, на форме справочника создается реквизит «Тип карты», далее я открываю список значений (справочник ДополнительныеСвойстваКошельков), ввожу туда например «MasterCard», «Visa», выбираю нужный мне, например «Visa», нажимаю записать, в регистр сведений записывается Кошелек1 ТипКарты Visa) Если создал 2 реквизита, то соответственно 2 строки (например: Кошелек1 Цвет Белый) и т.д., Вот не могу разобраться как это все реализовать, начал так как выложил выше и остановился на этом значении реквизита


  9. 1с-ник

    Offline

    1с-ник
    Профессионал в 1С
    Заблокирован

    Регистрация:
    5 окт 2014
    Сообщения:
    998
    Симпатии:
    164
    Баллы:
    104

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

         
    МенеджерЗаписи = РегистрыСведений.ЗначенияСвойствКошельков.СоздатьМенеджерЗаписи();
    Для Каждого Стр Из СозданныеРеквизиты Цикл
            // Заполнение
            МенеджерЗаписи.Записать();
    КонецЦикла;
    
  10. Вроде бы проблему решил, сделал по-другому чуть чуть, при нажатии кнопки сразу открывается форма РС, заполняю ее, записываю, дальше запросом вытаскиваю значения из РС и на основе их создаю реквизит и элемент формы, заполняю их данными с РС.
    Код формы элемента справочника:

    &НаКлиенте
    Процедура ПриОткрытии(Отказ)
        СозданиеРеквизита();
    КонецПроцедуры
    
    &НаКлиенте
    Процедура ДобавитьРеквизит(Команда)
        ПараметрыОткрытия = Новый Структура;
        ПараметрыОткрытия.Вставить("Кошелек", Объект.Ссылка);
        Закрытие = Новый ОписаниеОповещения ("ОписаниеЗакрытия", ЭтаФорма);
        ОткрытьФорму("РегистрСведений.ЗначенияСвойствКошельков.ФормаЗаписи",ПараметрыОткрытия,,,,,Закрытие);
    КонецПроцедуры
    
    &НаКлиенте
    Процедура ОписаниеЗакрытия(Результат,Параметры) Экспорт
        Если ТипЗнч(Результат) = Тип("Структура") Тогда
            СозданиеРеквизита();   
        КонецЕсли;
    КонецПроцедуры     
    
    &НаСервере
    Процедура СозданиеРеквизита() Экспорт
        Запрос = Новый Запрос;
        Запрос.Текст =
            "ВЫБРАТЬ
            |    ЗначенияСвойствКошельков.Свойство.Наименование КАК Наименование,
            |    ЗначенияСвойствКошельков.Свойство КАК Свойство,
            |    ЗначенияСвойствКошельков.Значение КАК Значение,
            |    СвойстваКошельков.ТипЗначения КАК ТипЗначения
            |ИЗ
            |    РегистрСведений.ЗначенияСвойствКошельков КАК ЗначенияСвойствКошельков
            |        ЛЕВОЕ СОЕДИНЕНИЕ ПланВидовХарактеристик.СвойстваКошельков КАК СвойстваКошельков
            |        ПО ЗначенияСвойствКошельков.Свойство = СвойстваКошельков.Ссылка
            |ГДЕ
            |    ЗначенияСвойствКошельков.Кошелек = &Кошелек";
        Запрос.УстановитьПараметр("Кошелек", Объект.Ссылка);
        РезультатЗапроса = Запрос.Выполнить();
        ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
        ГлобСвойство = Новый СписокЗначений;
        Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
            Если Элементы.Найти(СтрЗаменить(ВыборкаДетальныеЗаписи.Наименование," ","")) = Неопределено  Тогда
                НовыеРеквизиты = Новый Массив;
                НовыйРеквизит = Новый РеквизитФормы(СтрЗаменить(ВыборкаДетальныеЗаписи.Наименование," ",""),ВыборкаДетальныеЗаписи.ТипЗначения,"",ВыборкаДетальныеЗаписи.Наименование,Истина);
                НовыеРеквизиты.Добавить(НовыйРеквизит);
                ИзменитьРеквизиты (НовыеРеквизиты);
                Элемент = ЭтаФорма.Элементы.Добавить(СтрЗаменить(ВыборкаДетальныеЗаписи.Наименование," ",""),Тип("ПолеФормы"));
                Элемент.Вид = ВидПоляФормы.ПолеВвода;
                Элемент.ПутьКДанным = СтрЗаменить(НовыйРеквизит.Имя," ","");
                ЭтаФорма[СтрЗаменить(ВыборкаДетальныеЗаписи.Наименование," ","")] = ВыборкаДетальныеЗаписи.Значение;
               
            КонецЕсли;       
        КонецЦикла;
    КонецПроцедуры
    

    Код модуля формы записи РС:

    &НаСервере
    Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
        Если Параметры.Свойство("Кошелек") Тогда
            Запись.Кошелек = Параметры.Кошелек;
        КонецЕсли;
    КонецПроцедуры
    
    &НаКлиенте
    Процедура ПослеЗаписи(ПараметрыЗаписи)
        СписокПараметров = Новый Структура;
        СписокПараметров.Вставить("Свойство", Запись.Свойство);
        СписокПараметров.Вставить("Значение", Запись.Значение);
        ОповеститьОВыборе(СписокПараметров);
    КонецПроцедуры

    Проблема в том, как в элементе формы мне сделать отбор? Например я создал реквизит «цвет» (в ПВХ), создал значения для него «белый» и «черный» (в справочнике Доп.св-ва), а также создал реквизит «тип карты» со значениями «виза» и «мастеркард». На форме создались оба реквизита, а в поле ввода видно все 4 значения для обоих реквизитов(так как просто ссылается).
    Как мне ограничить выбор в поле ввода? Примерно так, чтобы из справочника Доп.св-ва брались только те значения, у которых свойство соответствует выбранному реквизиту.

  11. Доброго,
    в типовых решениях (БУ 3.0, УТ11, ЗУП 3.0) при добавлении «нового реквизита» (доп. реквизиты) на форму используется ГУИд при формировании его имени, соответственно, зная (имея возможность его получить) ГУИд доп. реквизита, совершенно спокойно можно найти нужный объект (элемент) формы :) и сделать с ним все, что необходимо

  12. Начинал делать так, создал список значений «добавленныеРеквизиты», попытался сделать отбор через СвязьПараметровВыбора, но не получилось.

    код в конце условия процедуры созданиереквизита:

                ДобавленныеРеквизиты.Добавить(ВыборкаДетальныеЗаписи.Свойство); 
                СвязьПараметра = Новый СвязьПараметраВыбора("Отбор.Владелец", "ДобавленныеРеквизиты");
                МассивПараметров = Новый Массив();
                МассивПараметров.Добавить(СвязьПараметра); 
                НовыеСвязи = Новый ФиксированныйМассив(МассивПараметров); 
                Элемент.СвязиПараметровВыбора = НовыеСвязи;
    

    Не получилось, т.к. в ДобавленныеРеквизиты записываются имена всех реквизитов, далее в поле выбора каждого реквизита я вижу характеристики, которые соответствуют всем этим созданным реквизитам. Работает правильно, только если я создаю 1 реквизит, как мне это исправить?


1C-pro.ru - форум по 1С:Предприятию 7.7, 8.0, 8.1, 8.2, 8.3

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

Данные объекта, которые отображаются в форме (в нашем случае данные документа), находятся всегда в основном реквизите формы. В подавляющем большинстве случаев этот реквизит имеет имя Объект. По крайней мере именно такое имя дает ему платформа, когда с помощью конструктора создает форму объекта. В нашем случае это именно так:


Основной реквизит формы содержит набор подчиненных реквизитов, соответствующих реквизитам прикладного объекта. Поэтому для того, чтобы обратиться, например, к поставщику, указанному в документе, нужно указать имя основного реквизита формы и через точку – имя подчиненного реквизита, хранящего ссылку на поставщика.

В нашем случае, для того чтобы получить ссылку на поставщика, нужно будет выполнить следующий код:

ПоставщикДокумента = Объект.Поставщик; 

 Как получить доступ к реквизитам формы?

Если реквизит объекта «вытащен» на форму, то реквизит формы можно получить через объект ЭлементыФормы, который содержит коллекцию элементов формы, сканируя ее в цикле:

ДокСсылка = СсылкаНаДокумент(ТипДокумента, НомерДок);
ДокОбъект = ДокСсылка.ПолучитьОбъект();
 
ФормаОбъекта = ДокОбъект.ПолучитьФорму();
Для Каждого Элемент Из ФормаОбъекта.ЭлементыФормы Цикл
        Сообщить(Элемент);
КонецЦикла;     
 

Этот цикл позволяет просмотреть имена а так же типы всех реквизитов формы, в том числе такие реквизиты как надписи, командные панели и тд.

Реквизиты формы могут быть различных типов. Поставив фильтр в виде типа реквизита мы можем просмотреть реквизиты определенного типа.

Если реквизит формы имеет тип «ТабличноеПоле», то можно такой элемент просканировать во вложенном цикле и узнать имена колонок таблицы:

 
Для Каждого Элемент Из ФормаОбъекта.ЭлементыФормы Цикл
        Сообщить(Элемент.Имя);
        Если Тип(Элемент) = Тип("ТабличноеПоле") Тогда
                Сообщить(" Это табличное поле! "  + Элемент.Имя );
                Для Каждого Колонка Из Элемент.Колонки Цикл
                        ИмяКолонки = Колонка.Имя;
                        Сообщить(ИмяКолонки);
                КонецЦикла;
        КонецЕсли;      
КонецЦикла;     
 

Как получить значение отдельного реквизита формы?

Чаще требуется получать не массив реквизитов формы,  а значение отдельных конкретных реквизитов формы. Например реквизиты «Шапки» или «Подвала» формы документа.

Пример:

 
ФормаОбъекта = ДокОбъект.ПолучитьФорму("ФормаДокумента");
Поставщик = ФормаОбъекта.ЭлементыФормы.Поставщик;
Поставщик = ФормаОбъекта.ЭлементыФормы.Получатель;
Сообщить(ФормаОбъекта.ЭлементыФормы.ТаблПоле.Колонки.Количество());
 

Реквизиты шапки могут иметь различные типы: Дата, СправочникСсылка, ЧекБокс, элемент раскрывающегося списка и др.

Как получить значение элементов табличной части формы?

Доступ к табличной части формы через объект

Доступ к табличной части формы (например: Товары) можно получить через объект:

 
  ДокОбъект = Док.ПолучитьОбъект(); //здесь Док - ссылка на объект
  //просканируем построчно таб часть документа
  Для Каждого Стр из ДокОбъект.Товары Цикл
      Номенклатура = Стр.Номенклатура;
      Стр.Коэффициент = 1;
  КонецЦикла;
 

Здесь ДокОбъект.Товары — это табличная часть «Товары» объекта. Далее в цикле табличная часть построчно сканируется!
В каждой итерации цикла можно получить доступ к любому полю строки указав через точку имя этого поля:

      Номенклатура = Стр.Номенклатура;

Доступ к табличной части формы через ЭлементыФормы

Табличная часть объекта и табличная часть формы объекта — это не одно и то же!

Для того, чтобы код работал правильно, надо чтобы колонка формы табчасти объекта в свойстве данные ссылалась на реквизит табличной части объекта. Этим определяется тип колонки таб части формы.

То есть должна быть установлена связь между реквизитом табчасти объекта и реквизитом табчасти формы. Форм у объекта метаданных может быть много мы знаем. Табличную часть формы объекта можно получить через объект ЭлементыФормы:

Объект ЭлементыФормы используется для доступа к элементам управления, расположенным на форме, в частности к таб части документа.

 
        ДокСсылка = СсылкаНаДокумент(ТипДокумента, НомерДок);
        ДокОбъект = ДокСсылка.ПолучитьОбъект();
                                
        ФормаОбъекта = ДокОбъект.ПолучитьФорму();
        Для Каждого Элемент Из ФормаОбъекта.ЭлементыФормы Цикл
                Если Тип(Элемент) = Тип("ТабличноеПоле") Тогда //элемент формы - табличное поле
                                                        
                        Если Элемент.Имя = "Товары" Тогда
                                Сообщить("Это табличное поле!! "  + Элемент.Имя );
                                
                                //ТабПоле = ФормаОбъекта.ЭлементыФормы.Товары.Значение;
                                ТабПоле = Элемент.Значение;
                                Колво = ТабПоле.Количество();
                                Сообщить("Количество строк: " + Колво); 
                                
                                Для Каждого ТекущаяСтрока Из ТабПоле Цикл
                                        
                                        Имя = ТекущаяСтрока.Номенклатура;
                                        Сообщить(Имя); 
                
                                КонецЦикла;                             
                                
                        КонецЕсли;      
                                                        
                КонецЕсли;                                      
        КонецЦикла;  
 

Результат для документа Авансовый отчет:

Это табличное поле!! Товары
Количество строк: 4
Женские ботфорты коричневые
Ботинки женские демисезонные
Ботинки женские натуральная кожа
Женские босоножки       

Если надо получить значение всех колонок всех строк, то организуем дважды вложенный цикл:
Во внешнем цикле сканируются строки, во внутреннем — колонки:

 
        ДокСсылка = СсылкаНаДокумент(ТипДокумента, НомерДок);
        ДокОбъект = ДокСсылка.ПолучитьОбъект();
                                
        ФормаОбъекта = ДокОбъект.ПолучитьФорму("ФормаДокумента");
        Для Каждого Элемент Из ФормаОбъекта.ЭлементыФормы Цикл
                Если Тип(Элемент) = Тип("ТабличноеПоле") Тогда
                                                        
                        Если Элемент.Имя = "ВыданныеАвансы" Тогда //таб часть объекта
                                Сообщить(" Это табличное поле!! "  + Элемент.Имя );
                                
                                ТабПоле = Элемент.Значение;
                                Индекс = 0;
                                Для Каждого ТекущаяСтрока Из ТабПоле Цикл
                                        
                                        Сообщить("=======================");
                                        Для Каждого Колонка Из Элемент.Колонки Цикл
                                                
                                                ИмяКолонки = Строка(Колонка.Имя);
                                                Сообщить(ИмяКолонки);
                                                Имя = ТекущаяСтрока[ИмяКолонки];//сработает только если есть такое поле таб части объекта
                                                Сообщить("=== " + Имя); 
                                                
                                        КонецЦикла;
                                        
                                        Индекс = Индекс + 1;
                                        Если Индекс > 0 Тогда break КонецЕсли; //только первая строка
                                        
                                        
                                КонецЦикла;                             
                                
                                                        
                        КонецЕсли;      
                                                        
                КонецЕсли;                                      
        КонецЦикла;    
 

Результат для документа Авансовый отчет:

Это табличное поле!! ВыданныеАвансы
=======================
НомерСтроки 1
ДокументАванса Расходный кассовый ордер ТК000000004 от 15.02.2007 19:24:03
СуммаДокументаАванса 300
ВалютаДокументаАванса USD
Выдано 300
Сумма 174

 Такое двойное сканирование удобно использовать для быстрой проверки того, что все колонки таб части формы имеют связь с реквизитами таб части объекта. Если такой связи у какой-либо колонки нет, система сгенерирует ошибку.

В данной статье описаны примеры программного создания объектов управляемой формы 1С : элементов, команд, реквизитов, а также описание стандартных возможностей для работы с ними.

Contents

  • 1 Введение в управляемая форма 1С реквизиты элементы команды
  • 2 Программное переопределение обработчиков событий формы и элементов формы
  • 3 Программное создание групп формы.
  • 4 Программное добавление команды на форму.
  • 5 Программное создание декораций форм.
  • 6 Программное добавление реквизита на форму.
  • 7 Вывод реквизитов на форму.
  • 8 Вызов процедур при создании на сервере 1С
  • 9 Некоторые советы при программном редактировании формы
  • 10 Полезные ссылки

Рекомендуется модифицировать управляемые формы типового решения 1С программно для удобного будущего обновления и исключения конфликтов, а также для удобной работы с изменениями и надежности при использовании механизма расширений.
В некоторых типовых конфигурациях 1С (ЕРП 2, УТ 11) используется механизм упрощенного изменения конфигурации. Статьи о типовом механизме можно найти в разделе полезных ссылок. Данный механизм используется в БСП, и его необходимо знать при модификации типовых конфигураций.
При добавлении элементов на форму программно можно отредактировать практически любое свойство из панель свойств, которое можно установить вручную в конфигураторе.
Также все описанные в текущем разделе процедуры и функции находятся во внешней обработке УпрФормы.

Примеры работы с объектом «ДанныеФормыКоллекция» и созданием дин. списка и таблицы значений программно можно будет посмотреть в части 2.

Для запуска обработки в режиме предприятия необходимо наличие объектов «Справочники.Номенклатура», подчиненный ему «Справочники.ХарактеристикиНоменклатуры» и «РегистрыСведений.ЦеныНоменклатуры”.

Программное переопределение обработчиков событий формы и элементов формы

Переопределить обработчики событий формы можно в обработчике «ПриСозданииНаСервере» (кроме самого обрабочика «ПриСозданииНаСервере») или в теле модуля формы в контексте сервера (например, Переопределение событий ПриЧтениинаСервере и ПриСозданииНаСервере).

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    ЭтаФорма.УстановитьДействие(“ОбработкаВыбора”, “пр_ОбработкаВыбора”)
КонецПроцедуры

В теле модуля формы:

#Если Сервер Тогда
    ЭтаФорма.УстановитьДействие("ПриСозданииНаСервере", "пр_ПриСозданииНаСервере");
#КонецЕсли

А в новой процедуре нужно добавить вызов основной, если такая процедура есть.

&НаСервере
Процедура пр_ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    ПриСозданииНаСервере(Отказ, СтандартнаяОбработка);
КонецПроцедуры

Аналогично можно поступить и с обработчиками элементов формы:

Элементы.Номенклатура.УстановитьДействие(“ПриИзменении”, “пр_НоменклатураПриИзменении”)

Программное создание групп формы.

&НаСервере
Процедура пр_СоздатьГруппы()
    
    ГруппаСтраницы =  Элементы.Добавить("пр_Страницы", Тип("ГруппаФормы"),ЭтаФорма);
    ГруппаСтраницы.Вид = ВидГруппыФормы.Страницы;
    
    НоваяСтраница = Элементы.Добавить("пр_Страница", Тип("ГруппаФормы"),ГруппаСтраницы);
    НоваяСтраница.Вид = ВидГруппыФормы.Страница;
    НоваяСтраница.Заголовок = "Страница 1";
    
    НоваяГруппа = Элементы.Добавить("пр_Группа1", Тип("ГруппаФормы"),НоваяСтраница);
    НоваяГруппа.Вид = ВидГруппыФормы.ОбычнаяГруппа;
    НоваяГруппа.Группировка = ГруппировкаПодчиненныхЭлементовФормы.ГоризонтальнаяЕслиВозможно;
    НоваяГруппа.Заголовок = "Группа 1";
    
КонецПроцедуры

Доступные виды групп формы:

Программное добавление команды на форму.

Удалить команду можно при помощи метода коллекции формы команд: Команды.Удалить(<Команда>). Удалять можно только те команды, которые были созданы программно.

&НаСервере
Процедура пр_СоздатьНовуюКоманду()
    
    //создать новую команду у формы
    НоваяКоманда    		 = Команды.Добавить("пр_Команда1");
    НоваяКоманда.Действие     = "пр_Команда1";
    НоваяКоманда.Картинка     = БиблиотекаКартинок.Облако;
    НоваяКоманда.Отображение = ОтображениеКнопки.Картинка;
    
    //вывести команду в элементы
    ЭлементКоманда    			 = Элементы.Добавить("пр_Команда1", Тип("КнопкаФормы"), Элементы.ФормаКоманднаяПанель);
    ЭлементКоманда.Заголовок     = "Вывести сообщение";
    ЭлементКоманда.ИмяКоманды     = "пр_Команда1";

    //удалить команду
    //Команды.Удалить(НоваяКоманда);
    
КонецПроцедуры

&НаКлиенте
Процедура пр_Команда1(Команда)
    
    Сообщить("Команда выполнена.");
    
КонецПроцедуры

Программное создание декораций форм.

&НаСервере
Процедура пр_СоздатьДекорацию()
    
    //добавить надпись
    Элемент    			 = Элементы.Добавить("Надпись1", Тип("ДекорацияФормы"), Элементы["пр_Группа1"]);
    Элемент.Вид    		 = ВидДекорацииФормы.Надпись;
    Элемент.Заголовок    	 = "Добавленная надпись";
 
    //для того, чтобы добавить картинку, необходимо выбрать ВидДекорацииФормы.Картинка
    Элемент = Элементы.Добавить("Картинка1", Тип("ДекорацияФормы"), Элементы["пр_Группа1"]);
    Элемент.Вид = ВидДекорацииФормы.Картинка;
    Элемент.Картинка = БиблиотекаКартинок.Бесконечность;  
  
КонецПроцедуры

Программное добавление реквизита на форму.

Добавлять новые реквизиты в управляемую форму и удалять необходимо с помощью метода ИзменитьРеквизиты(), куда в параметры передается массив добавляемых реквизитов и массив удаляемых. Удалять при этом можно только те реквизиты, которые были созданы программно.

&НаСервере
Процедура пр_СоздатьРеквизиты()
    
	// Массив для новых реквизитов
	ДобавляемыеРеквизиты    = Новый Массив;
   	 
	// Опишем ревизиты формы
	Реквизит_Использование = Новый РеквизитФормы("пр_Использование",    Новый ОписаниеТипов("Булево"), "", "Использование");
	Реквизит_Номенклатура = Новый РеквизитФормы("пр_Номенклатура",    Новый ОписаниеТипов("СправочникСсылка.Номенклатура"), "", "Номенклатура");
	Реквизит_Характеристика = Новый РеквизитФормы("пр_Характеристика",    Новый ОписаниеТипов("СправочникСсылка.ХарактеристикиНоменклатуры"), "", "Характеристика");
  	 Реквизит_Количество = Новый РеквизитФормы("пр_Количество",    Новый ОписаниеТипов("Число", , , Новый КвалификаторыЧисла(10, 3)), "", "Количество");
  	 Реквизит_УдалитьКоличество = Новый РеквизитФормы("пр_УдалитьКоличество",    Новый ОписаниеТипов("Число", , , Новый КвалификаторыЧисла(10, 3)), "", "Удалить_Количество");
       //если используется БСП, то можно для определения описания типов использовать функцию
       //ОбщегоНазначения.ОписаниеТипаСтрока(ДлинаСтроки)
       //ОбщегоНазначения.ОписаниеТипаЧисло(Разрядность, РазрядностьДробнойЧасти = 0, ЗнакЧисла = Неопределено)
       //ОбщегоНазначения.ОписаниеТипаДата(ЧастиДаты)
  	 Реквизит_Информация = Новый РеквизитФормы("пр_Информация",    ОбщегоНазначения.ОписаниеТипаСтрока(100), "", "Информация");
    
       // Для наглядности заполним массив после описания реквизитов формы
	ДобавляемыеРеквизиты.Добавить(Реквизит_Использование);
	ДобавляемыеРеквизиты.Добавить(Реквизит_Номенклатура);
	ДобавляемыеРеквизиты.Добавить(Реквизит_Характеристика);
	ДобавляемыеРеквизиты.Добавить(Реквизит_Количество);
	ДобавляемыеРеквизиты.Добавить(Реквизит_УдалитьКоличество);
	ДобавляемыеРеквизиты.Добавить(Реквизит_Информация);
    
	// Добавим новые реквизиты в форму
	ИзменитьРеквизиты(ДобавляемыеРеквизиты);
   	 
КонецПроцедуры

&НаСервере
Процедура пр_УдалитьРеквизиты()
    
	// Массив для удаляемых реквизитов
	УдаляемыеРеквизиты    = Новый Массив;
    
    //указываем путь к удаляемому реквизиту
	УдаляемыеРеквизиты.Добавить("пр_УдалитьКоличество");
    //К добавленным реквизитам нужно обращаться через переменную ЭтаФорма
    
	// Добавим новые реквизиты в форму
	ИзменитьРеквизиты(,УдаляемыеРеквизиты);
   	 
КонецПроцедуры

Вывод реквизитов на форму.

&НаСервере
Процедура пр_ВывестиРеквизитыНаФорму()
    
    НовыйЭлемент = Элементы.Добавить("пр_Использование", Тип("ПолеФормы"), Элементы.пр_Страница1);
	НовыйЭлемент.ПутьКДанным              	= "пр_Использование";
	НовыйЭлемент.Вид                      	= ВидПоляФормы.ПолеФлажка;
    НовыйЭлемент.ПоложениеЗаголовка    	   = ПоложениеЗаголовкаЭлементаФормы.Право;
    //установим обработчик события элементы
    НовыйЭлемент.УстановитьДействие("ПриИзменении", "пр_ИспользованиеПриИзменении");
    
    НовыйЭлемент = Элементы.Добавить("пр_Номенклатура", Тип("ПолеФормы"), Элементы.пр_Страница1);
	НовыйЭлемент.ПутьКДанным              	= "пр_Номенклатура";
	НовыйЭлемент.Вид                      	= ВидПоляФормы.ПолеВвода;
    //установить параметр выбора элемента
    НовыйМассив = Новый Массив();
    НовыйПараметр = Новый ПараметрВыбора("Отбор.ПометкаУдаления", Ложь);
    НовыйМассив.Добавить(НовыйПараметр);
    НовыеПараметры = Новый ФиксированныйМассив(НовыйМассив);
	НовыйЭлемент.ПараметрыВыбора = НовыеПараметры;
    НовыйЭлемент.УстановитьДействие("ПриИзменении", "пр_НоменклатураПриИзменении");

    НовыйЭлемент = Элементы.Добавить("пр_Характеристика", Тип("ПолеФормы"), Элементы.пр_Страница1);
	НовыйЭлемент.ПутьКДанным              	= "пр_Характеристика";
	НовыйЭлемент.Вид                      	= ВидПоляФормы.ПолеВвода;
	НовыйЭлемент.Заголовок                	= "Характеристика номенклатуры";
    //добавить связь параметров выбора по реквизиту владелец в зависимости от выбранной номенклатуры
    НоваяСвязь = Новый СвязьПараметраВыбора("Отбор.Владелец", "пр_Номенклатура");
    НовыйМассив = Новый Массив();
    НовыйМассив.Добавить(НоваяСвязь);
	НовыйЭлемент.СвязиПараметровВыбора = Новый ФиксированныйМассив(НовыйМассив);    
    НовыйЭлемент.УстановитьДействие("ПриИзменении", "пр_ХарактеристикаПриИзменении");
    
    НовыйЭлемент = Элементы.Добавить("пр_Количество", Тип("ПолеФормы"), Элементы.пр_Страница1);
	НовыйЭлемент.ПутьКДанным              	= "пр_Количество";
	НовыйЭлемент.Вид                      	= ВидПоляФормы.ПолеВвода;
    //установить формат
	НовыйЭлемент.ФорматРедактирования   	   = "ЧДЦ=0; ЧРГ=.; ЧН=Отсутствует";
    
    НовыйЭлемент = Элементы.Добавить("пр_Информация", Тип("ПолеФормы"), Элементы.пр_Страница1);
	НовыйЭлемент.ПутьКДанным              	= "пр_Информация";
	НовыйЭлемент.Вид                      	= ВидПоляФормы.ПолеВвода;
    //установить список выбора
    НовыйЭлемент.РежимВыбораИзСписка    	   = Истина;
    Массив = Новый Массив;
    Массив.Добавить("Необходимо дозаказать");    
    Массив.Добавить("Достаточно");    
    Массив.Добавить("Оформить полный заказ");    
    НовыйЭлемент.СписокВыбора.ЗагрузитьЗначения(Массив);
    
КонецПроцедуры

&НаКлиенте
Процедура пр_ИспользованиеПриИзменении(Элемент)
КонецПроцедуры

Вызов процедур при создании на сервере 1С

После описания всех процедур выводим их в процедуре ПриСозданииНаСервере. Также можно изменить программно некоторые свойства формы, например, заголовок. Чтобы был виден только наш заголовок, нужно отключить свойство Автозаголовок.

&НаСервере

&НаСервере
Процедура пр_ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	//установим заголовок формы 
	ЭтаФорма.Заголовок 		= "Шаблон для программной работы с реквизитами, командами и элементами формы";
	ЭтаФорма.АвтоЗаголовок 	= Ложь;
	
	пр_СоздатьГруппы();
	пр_СоздатьНовуюКоманду();
	пр_СоздатьДекорацию();
	пр_СоздатьРеквизиты();
	пр_УдалитьРеквизиты();
	пр_ВывестиРеквизитыНаФорму();
	
КонецПроцедуры

Некоторые советы при программном редактировании формы

  • Если вы не используете префиксы при создании новых команд и элементов рекомендуется проверять существование создаваемых объектов по имени с помощью метода Найти(), который вернет Неопределено, если объект в коллекции не найден:
    • Элементы.Найти(«пр_Владелец»);
    • Команды.Найти(«пр_НоваяКоманда»);
  • Чтобы проверить уникальность реквизита на форме можно воспользоваться следующей функцией:
&НаКлиентеНаСервереБезКонтекста
// Функция определяет существует ли реквизит у объекта.
//
Функция ЕстьРеквизитОбъекта(мОбъект, ИмяРеквизита)
    
    КлючУникальности   = Новый УникальныйИдентификатор;
    СтруктураРеквизита = Новый Структура(ИмяРеквизита, КлючУникальности);
    ЗаполнитьЗначенияСвойств(СтруктураРеквизита, мОбъект);
    Возврат СтруктураРеквизита[ИмяРеквизита] <> КлючУникальности;
    
КонецФункции // ЕстьРеквизитОбъекта()
  • Свойства, методы и коллекции управляемой формы описаны в синтакс-помощнике в разделе «Интерфейс (управляемый)»;
  • Изучите БСП, если она имеется в вашей конфигурации. Например в общем модуле «ОбщегоНазначения» уже описаны функции для создания объекта ОписаниеТипов, необходимого при создании новых реквизитов на форме:
    • ОбщегоНазначения.ОписаниеТипаСтрока(ДлинаСтроки) — Создает объект ОписаниеТипов, содержащий тип Строка;
    • ОбщегоНазначения.ОписаниеТипаЧисло(Разрядность, РазрядностьДробнойЧасти = 0, ЗнакЧисла = Неопределено) — Создает объект ОписаниеТипов, содержащий тип Число;
    • ОбщегоНазначения.ОписаниеТипаДата(ЧастиДаты) — Создает объект ОписаниеТипов, содержащий тип Дата;
    • ОбщегоНазначенияВызовСервера.ЦветСтиля(ИмяЦветаСтиля) — Функция получает цвет стиля по имени элемента стиля;
    • ОбщегоНазначенияВызовСервера.ШрифтСтиля(ИмяШрифтаСтиля) — Функция получает шрифт стиля по имени элемента стиля.

Итак, взглянем на получившийся результат. Все элементы на форме созданы программно:

Полезные ссылки

1. Типовой механизм упрощенного изменения конфигурации в ERP 2.0 и УТ 11
2. Типовой функционал модификации конфигурации линейки ERP-решений (УТ 11, КА 2 и ERP 2)
3. 1С Управляемые Формы. Программное создание таблицы значений и динамического списка (Часть 2)

34 / 34 / 8

Регистрация: 13.06.2014

Сообщений: 509

1

1C 8.x

Обращение к реквизиту

26.09.2014, 17:09. Показов 2096. Ответов 8


Всем привет, помогите начинающему нубу в 1с
У меня в документах есть страховой акт, в реквизитах которого есть страховой продукт.
Я делаю форму печати страхового акта, в которой предварительно нужно сделать проверку на тип продукта
Подскажите как обратиться к этому элементу в общих чертах



0



wladimir_ui

Шизофреник

360 / 362 / 83

Регистрация: 25.06.2013

Сообщений: 1,141

26.09.2014, 17:24

2

сравнить тип продукта с нужным… варианты (пара из кучи) в общих чертах

1C
1
2
3
Если СтраховойПродукт.ТипПродукта = Перечисления.ТипыПродуктов.КакойтоСравниваемыйТип Тогда
   //ВашиТелодвижения
КонецЕсли
1C
1
2
3
Если Страховой продукт.ТипПродукта = Справочники.ТипыПродуктов.НайтиПоКоду/Наименованию(Код/Наименование) Тогда
   //ВашиТелодвижения
КонецЕсли



1



286 / 186 / 18

Регистрация: 20.02.2012

Сообщений: 925

26.09.2014, 17:27

3

отмена



0



Joker_vad

Эксперт 1С

476 / 413 / 93

Регистрация: 26.09.2012

Сообщений: 1,907

26.09.2014, 17:54

4

можно еще

1C
1
Объект.СтраховойПродукт.ТипПродукта



1



frostyfull

34 / 34 / 8

Регистрация: 13.06.2014

Сообщений: 509

29.09.2014, 10:32

 [ТС]

5

wladimir_ui, чет у меня непонятки какие-то
У меня сравнение по конкретному параметру идет, если написать «страховой продукт», то после точки «тип продукта» не высвечивается

1C
1
2
3
4
5
6
7
8
9
10
Процедура ПриОткрытии()
    ВидВыплаты = "ВыплатаРС";
    Если Не  = ДАГО Тогда
        ЭлементыФормы.НадписьРазмерВыплатыОСАГО.Видимость = Ложь;
        ЭлементыФормы.РазмерВыплатыОСАГО.Видимость = Ложь;
    Иначе 
        ЭлементыФормы.НадписьРазмерВыплатыОСАГО.Видимость = Истина;
        ЭлементыФормы.РазмерВыплатыОСАГО.Видимость = Истина;
    КонецЕсли;
КонецПроцедуры

После «если не» надо указать реквизит
Прошу прощения если туплю, я вообще пока не въезжаю как работает 1С )



0



SonicQ

286 / 186 / 18

Регистрация: 20.02.2012

Сообщений: 925

29.09.2014, 10:34

6

Цитата
Сообщение от frostyfull
Посмотреть сообщение

Если Не = ДАГО Тогда

? Что сравниваешь то?

1C
1
????=ДАГО



0



34 / 34 / 8

Регистрация: 13.06.2014

Сообщений: 509

29.09.2014, 11:01

 [ТС]

7

SonicQ, а, точно, забыл написать)
Сравниваю с реквизитом страхового акта, к которому тоже не знаю как обратиться, но в конфигурации он находится в разделе «документы»
Если написать «Документы.СтраховойАкт» то после точки высвечиваются всякие функции, такие как Выбрать, Найти…, Получить… и т.д.

Добавлено через 1 минуту
И проверка должна быть по реквизиту того акта, из которого вызывается эта форма



0



286 / 186 / 18

Регистрация: 20.02.2012

Сообщений: 925

29.09.2014, 11:26

8

Лучший ответ Сообщение было отмечено frostyfull как решение

Решение

1. Создаешь реквизит на открываемой форме
2. В модуле страхового акта, в том месте где ты открываешь форму пишешь код с рисунка 2
3. В модуле открываемой формы пишешь свою проверку
4. Смотришь результат

Пример в рисунках



1



34 / 34 / 8

Регистрация: 13.06.2014

Сообщений: 509

29.09.2014, 11:43

 [ТС]

9

SonicQ, спасибо, похоже на правду)



0



IT_Exp

Эксперт

87844 / 49110 / 22898

Регистрация: 17.06.2006

Сообщений: 92,604

29.09.2014, 11:43

9

Содержание:

1.    Реквизиты объекта и реквизиты формы в 1С

2.    Как получить значения из элементов формы 1С  

1.    Реквизиты объекта и реквизиты формы в 1С

В обычном приложении у элемента формы 1С 8.3 было свойство «Значение», доступное как для чтения, так и для записи. Какой аналог в управляемом приложении?

Элементы формы 1С 8.3 могут содержать реквизиты двух видов: реквизиты объекта 1С и реквизиты формы.

Красным помечен реквизит объекта 1С Контрагент, а зеленым – реквизит формы в 1С.

Интерактивно выберем эти элементы в пользовательском режиме 1С и попробуем прочитать их «программно» кнопкой «Прочитать».

Если читать значения реквизитов в клиентской процедуре, то код для 1С Предприятия будет следующий:


Все бы хорошо: мы получили на клиенте значения реквизитов объекта 1С и формы, но – не значения элементов формы 1С. На клиенте значение элементов формы 1С получить нельзя. 

2.    Как получить значения из элементов формы 1С

Чтобы получить значения из элементов формы 1С, нам потребуется серверный вызов:

Именно на сервере у элемента формы 1С 8.3 становится доступно свойство ПутьКДанным, по которому его можно извлечь либо из Объекта, который имеет тип ДанныеФормыСтруктура:

…либо из Формы, которая имеет тип ФормаКлиентскогоПриложения:


Форма и ее элементы не видны на сервере без контекста. То есть код для 1С:Предприятия выдаст множество ошибок.

Также Форму нельзя передать как параметр в процедуру и функцию на сервер или в общий модуль.


            Еще хочется разобрать момент, когда нам возможно увидеть состояние различающихся значений в элементе форме 1С и в объекте. Это возможно в событии элемента ОбработкаВыбора.
Например, при значении поля Контрагент — Ассоль, мы выбрали контрагента Бакалея:


Новое значение доступно как параметр процедуры ВыбранноеЗначение.


Система дает шанс что-то сделать в этой ситуации.

Специалист компании ООО «Кодерлайн»

Добрыгин Михаил

Понравилась статья? Поделить с друзьями:
  • 1с программно заполнить дополнительный реквизит документа
  • 1с расширение конфигурации добавить реквизит в справочник
  • 1с расширение конфигурации добавление реквизита документа
  • 2 й мосфильмовский пер д 8а судебные приставы часы работы
  • 200 тысяч рублей на развитие бизнеса безвозмездно условия