1С регистр сведений на форме справочника

Рассмотрим задачу создания формы, которая позволит редактировать номенклатуру и одновременно ее цены. Для решения этой задачи используем информационную базу демонстрационного примера Web-расширения.

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

С помощью Помощника создаем в среде Visual Studio новый проект; в качестве базы данных выберем информационную базу Демонстрационного примера Web-расширения.

Далее, воспользовавшись шаблоном V8ListForm , создаем форму списка для справочника "Номенклатура". Полученную форму устанавливаем как стартовую форму приложения.

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

Теперь необходимо добавить источники данных для цен номенклатуры. Для этого в форме размещаем три элемента управления V8RecordDataSource . Элемент управления V8RecordDataSource предназначен для работы с записями регистров. В окне Properties задаем свойства этих элементов управления:

Свойство Значение
ID DSОптоваяЦена
InitByRequest False
TableName РегистрСведений.ЦеныНоменклатуры
Свойство Значение
ID DSМелкоОптоваяЦена
InitByRequest False
TableName РегистрСведений.ЦеныНоменклатуры
Свойство Значение
ID DSРозничнаяЦена
InitByRequest False
TableName РегистрСведений.ЦеныНоменклатуры

Значение свойства InitByRequest мы устанавливаем равным False , так как параметры, которые будут передаваться в эту форму через строку запроса (значение ключевого поля, например), относятся в элементу справочника "Номенклатура", а не к регистру сведений.

У каждого из элементов управления V8RecordDataSource в коллекцию Fields необходимо добавить элемент со свойством Name – Цена . Именно это поле мы будем редактировать при помощи нашей формы.

Далее в таблицу, в которой размещены поля ввода, добавляем три строки. В первой колонке этих строк указываем наименование типа цен: «Оптовая цена», «Мелкооптовая цена», «Розничная цена», а во второй колонке размещаем три элемента управления V8TextBox , у которых устанавливаем следующие значения свойств:

Свойство Значение
ItemDataSource DSОптоваяЦена
FieldName Цена
Свойство Значение
ItemDataSource DSМелкоОптоваяЦена
FieldName Цена
Свойство Значение
ItemDataSource DSРозничнаяЦена
FieldName Цена

Таким образом, мы связали поля ввода ( V8TextBox ) с источниками данных ( V8RecordDataSource ).

Теперь необходимо обеспечить синхронизацию источников данных.

В первую очередь напишем метод, который заполняет значения ключевых полей (измерений) для источников данных регистра сведений.

Читайте также:  Рисование фигур в фотошопе

private void FillValues()
<
DSОптоваяЦена.KeyValues = new object[2];
DSМелкоОптоваяЦена.KeyValues = new object[2];
DSРозничнаяЦена.KeyValues = new object[2];

DSОптоваяЦена.KeyValues[0] = ItemDataSource.KeyValue;
DSМелкоОптоваяЦена.KeyValues[0] = ItemDataSource.KeyValue;
DSРозничнаяЦена.KeyValues[0] = ItemDataSource.KeyValue;

V8DbSelectCommand command = new V8DbSelectCommand();
command.Connection = ItemDataSource.Connection;

bool needClose = ItemDataSource.Connection.State == ConnectionState.Closed;
if (ItemDataSource.Connection.State == ConnectionState.Closed)
ItemDataSource.Connection.Open();
try
<
command.CommandText = "SELECT Ссылка FROM Справочник.ТипыЦен WHERE Наименование="Оптовая"";
DSОптоваяЦена.KeyValues[1] = command.ExecuteScalar();

command.CommandText = "SELECT Ссылка FROM Справочник.ТипыЦен WHERE Наименование="Мелкооптовая"";
DSМелкоОптоваяЦена.KeyValues[1] = command.ExecuteScalar();

command.CommandText = "SELECT Ссылка FROM Справочник.ТипыЦен WHERE Наименование="Розничная"";
DSРозничнаяЦена.KeyValues[1] = command.ExecuteScalar();
>
finally
<
if (needClose)
ItemDataSource.Connection.Close();
>
>

В этом методе для каждого источника данных мы создаем массив для хранения значений ключевых полей. Массив содержит два элемента, по числу измерений регистра сведений "ЦеныНоменклатуры" ("Номенклатура" и "ТипЦен"). Значением измерения "Номенклатура" является ссылка на редактируемый в этой форме элемент справочника "Номенклатура". Значение этой ссылки содержится в свойстве KeyValue источника данных ItemDataSource .

Значения для измерения "ТипЦен" мы получаем при помощи запроса, воспользовавшись объектом V8DbSelectCommand для каждого типа цен.

Это метод мы будем использовать для инициализации источников данных при редактировании номенклатуры или создании новой.

Далее создаем обработчик OnInitObject элемента управления ItemDataSource . Это событие возникает при создании нового элемента справочника "Номенклатура".

private void ItemDataSource_OnInitObject(object source, _1C.V8.WebControls.V8ItemDataSourceInitObjectEventArgs e)
<
FillValues();

DSОптоваяЦена.Connection = ItemDataSource.Connection;
DSОптоваяЦена.InitNew();

DSМелкоОптоваяЦена.Connection = ItemDataSource.Connection;
DSМелкоОптоваяЦена.InitNew();

DSРозничнаяЦена.Connection = ItemDataSource.Connection;
DSРозничнаяЦена.InitNew();
>

В этом обработчике мы заполняем значения ключевых полей источников данных регистра и, используя соединение «ведущего» источника данных ( ItemDataSource ), инициализируем их.

Стоит обратить внимание на использование свойства Connection «ведущего» источника данных. Данная техника является предпочтительной, так как сокращает количество COM-соединений с 1С:Предприятием, а также позволяет осуществлять запись данных в одной транзакции.

Теперь напишем метод для синхронизации чтения данных. Для этого создаем обработчик события OnRead элемента управления ItemDataSource .

private void ItemDataSource_OnRead(object source, System.EventArgs e)
<
FillValues();

DSОптоваяЦена.Connection = ItemDataSource.Connection;
DSОптоваяЦена.Read(DSОптоваяЦена.KeyValues);
if (DSОптоваяЦена.dataSet.Tables[0].Rows.Count == 0)
DSОптоваяЦена.InitNew();

DSМелкоОптоваяЦена.Connection = ItemDataSource.Connection;
DSМелкоОптоваяЦена.Read(DSМелкоОптоваяЦена.KeyValues);
if (DSМелкоОптоваяЦена.dataSet.Tables[0].Rows.Count == 0)
DSМелкоОптоваяЦена.InitNew();

DSРозничнаяЦена.Connection = ItemDataSource.Connection;
DSРозничнаяЦена.Read(DSРозничнаяЦена.KeyValues);
if (DSРозничнаяЦена.dataSet.Tables[0].Rows.Count == 0)
DSРозничнаяЦена.InitNew();
>

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

Значения цен необходимо отобразить на форме. Создаем обработчик события BeforeSetDataToForm элемента управления V8ItemDataSource .

private void ItemDataSource_BeforeSetDataToForm(object source, System.EventArgs e)
<
DSОптоваяЦена.SetDataToForm();
DSМелкоОптоваяЦена.SetDataToForm();
DSРозничнаяЦена.SetDataToForm();
>

Читайте также:  Bn41 01537a не включается

Переходим к процессу записи данных. В первую очередь необходимо значения ключевых полей исотчников данных регистра перенести в записываемый набор данных. Для каждого элемента управления V8RecordDataSource создаем обработчик события BeforeWrite .

private void DSОптоваяЦена_BeforeWrite(object source, System.EventArgs e)
<
DataRow row = DSОптоваяЦена.dataSet.Tables[0].Rows[0];
row["Номенклатура"] = ItemDataSource.KeyValue;
row["ТипЦен"] = DSОптоваяЦена.KeyValues[1];
>
private void DSМелкоОптоваяЦена_BeforeWrite(object source, System.EventArgs e)
<
DataRow row = DSМелкоОптоваяЦена.dataSet.Tables[0].Rows[0];
row["Номенклатура"] = ItemDataSource.KeyValue;
row["ТипЦен"] = DSМелкоОптоваяЦена.KeyValues[1];
>
private void DSРозничнаяЦена_BeforeWrite(object source, System.EventArgs e)
<
DataRow row = DSРозничнаяЦена.dataSet.Tables[0].Rows[0];
row["Номенклатура"] = ItemDataSource.KeyValue;
row["ТипЦен"] = DSРозничнаяЦена.KeyValues[1];
>

Данные находятся в объекте dataSet источника данных. Значение измерения Номенклатура мы берем из «ведущего» источника данных, так как это значение могло измениться (в случае записи нового элемента справочника "Номенклатура").

Последний метод, который мы должны реализовать – это обработчик события OnWrite элемента управления ItemDataSource . Этот обработчик вызывается после сохранения данных «ведущего» источника данных.

private void ItemDataSource_OnWrite(object source, System.EventArgs e)
<
try
<
DSОптоваяЦена.Connection = ItemDataSource.Connection;
DSОптоваяЦена.doSave();

DSМелкоОптоваяЦена.Connection = ItemDataSource.Connection;
DSМелкоОптоваяЦена.doSave();

DSРозничнаяЦена.Connection = ItemDataSource.Connection;
DSРозничнаяЦена.doSave();
>
catch (Exception ex)
<
V8WebUtil.RegisterShowErrorScript(ex.GetBaseException().Message, this, false);
>
>

В этом методе мы вызываем сохранение данных источников регистра сведений, используя соединение «ведущего» источника. Таким образом, запись данных происходит в одной транзакции. В случае возникновения ошибки мы регистрируем скрипт для ее отображения.

В результате мы получили форму, с помощью которой мы можем создавать и редактировать записи справочника "Номенклатура", одновременно редактируя ее цены.

Файлы формы ( V8WebItemFrom1.aspx и V8WebItemForm1.aspx.cs ) находятся в каталоге 1CITSEXEWeb

ВЫ МОЖЕТЕ ПРЯМО СЕЙЧАС СКОПИРОВАТЬ ФОРМУ
НА ЖЕСТКИЙ ДИСК ВАШЕГО КОМПЬЮТЕРА

Как на управляемой форме разместить список регистра сведений с отбором?

Решение рассмотрено для элемента справочника (Контрагент и регистр КонтактнаяИнформация)

1. Создание реквизита:
Добавляем новый реквизит формы (. не путать с реквизитом справочника . ) с типом "ДинамическийСписок"
В поле "Основная таблица" выбираем нужный регистр сведений.

2. Отображение на форме:
Перетащить реквизит формы в элементы формы (c права налево .
Так же для отображения необходимо задать хотя-бы одну колонку для вывода.

3. Настройка отбора:
В процедуре ПриСозданииНаСервере вручную устанавливаем необходимый отбор.

Пример:
Код 1C v 8.2 УП

Решение явно не единственное, так что если кто что накопает ещё — пишите 😉

Похожие FAQ

Еще в этой же категории

Заполнение списка значений в элементе поле выбора на форме 10
//Заполнение списка перебором данных // Элемент формы МетаданныеВыбор имеет тип — Произвольный, Использование — Режим выбора из Списка, кнопка списка Для Каждого Метаданное из Метаданные.РегламентныеЗадания Цикл ЭлементыФормы.МетаданныеВыбор.Спи Как установить параметр динамического списка? 9
Когда используете для вывода данных динамический список и произвольный запрос, то бывают ситуации когда надо указать параметр используемый в этом запросе. Ниже пример вывода данных регистра сведений в карточке клиента Для вывода используется исп Как обновить динамический список или реквизит на форме клиента? 7
Если вы, открыв форму справочника или документа, выполнили некоторое действие, код который должен изменить состояние данных в динамических списках или значение реквизита. Данные изменены, но в открытой форме осталось все как было, можно конечно закр Форма

Читайте также:  Harry potter новая игра

Программное создание таблицы значений с условным оформлением 6
Как создать на форме таблицу и сделать для нее подсветку содержимого колонки в строке по условию? Итак для начала нам надо добавить реквизиты в форму. Для этого у нас есть метод: ИзменитьРеквизиты(). Перед тем как его использовать мы сформируем ма Форма

Задача

Решение

Устанавливается отбор не в наборе записей «ИсторияОповещений», а в свойстве табличного поля ОтборСтрок

НастройкаОтбор = ЭлементыФормы.ИсторияОповещений.ОтборСтрок;
НастройкаОтбор.Партнер.ВидСравнения = ВидСравнения.Равно;
НастройкаОтбор.Партнер.Значение = Ссылка;
НастройкаОтбор.Партнер.Использование = Истина;

Если у вас ТипЗначения источника «РегистрСведенийНаборЗаписей», тогда далее, считывается этот набор и обновляются строки табличного поля

Если это «РегистрСведенийСписок», тогда считывание не нужно, но отбор как раз у объекта ИсторияОповещений.Отбор, а не элемента формы.

В табличном поле есть свойство «Обновлять при изменении отбора», но она в данном случае не отрабатывает, скорее всего применяется для интерактивного изменения отбора.

Тем не менее, рекомендую его устанавливать, хуже точно не будет.

Если записи регистра сведений часто изменяются (пока открыта форма элемента):

  • следует обновлять табличное поле через механизм оповещений, так как в свойствах табличного поля регистра сведений, нет возможности установить интервал обновления (в отличии от списка документов);
  • принудительно через интервал времени, задействовав «Обработчик ожидания»;
  • добавить кнопку «Обновить» для табличного поля.

Люди глупо доверчивы… Вся реклама мира основана на трех принципах: «Хорошо, много и даром». Поэтому можно давать скверно, мало и дорого.