- •От автора курса
- •Содержание Урок 1.
- •Урок 2.
- •Урок 3.
- •Урок 4.
- •Занятие 1.01
- •Занятие 1.02
- •Занятие 1.03
- •Занятие 1.04
- •Занятие 1.05
- •Занятие 1.06
- •Занятие 1.07
- •Занятие 1.08
- •Занятие 1.09
- •Занятие 1.10
- •Занятие 1.11
- •Занятие 1.12
- •Занятие 1.13
- •Занятие 1.14
- •Занятие 1.15
- •Занятие 1.16
- •Занятие 1.17
- •Занятие 1.18
- •Занятие 2.19
- •С корреспонденцией
- •Без корреспонденции
- •Занятие 2.20
- •Занятие 2.21
- •Занятие 2.22
- •Занятие 2.23
- •Занятие 2.24
- •Занятие 3.25 расчет
- •Занятие 3.26
- •Занятие 3.27
- •Занятие 3.28
- •Занятие 3.29
- •Занятие 3.30
- •Перерасчеты
Занятие 1.06
Если конфигурация создается под 8.2, то в ней уже отключены свойства, связанные с формами Толстого клиента. Но если надо будет конвертировать базу с версии 8.1 или потребуется режим Толстого клиента, обычные формы:
«Сервис – Параметры - Общие»
«Управляемое приложение и обычное приложение» - тогда у конфигурации появятся свойства:
«Использовать управляемые формы в обычном приложении»
«Использовать обычные формы в управляемом приложении»
Позволяют открывать обычные формы в толстом клиенте в режиме эмуляции тонкого клиента и наоборот.
Сделаем, чтобы группы выводились жирным курсивом и отбор вывода только товаров без услуг.
В форме отчета добавим реквизит:
Имя – «ПечататьТолькоТовары».
Заголовок – «Печатать только товары».
Тип – «Булево».
Реквизит разместим в группе. Свойства группы:
Отображение – «Нет».
ОтображатьЗаголовок – «Ложь».
Способ 1:
«Отбор» - один из параметров метода «ВыбратьИерархически()». Отбор можно установить на реквизиты «Код», «Наименование» и те, у которых свойство:
Индексировать – «Индексировать с доп. упорядочиванием» - система будет производить индексирование с символьным упорядочиванием значения, т.е. не только по значению, а еще и по символьному представлению значения.
Установим это свойство реквизиту «Услуга» и проведем отбор по нему:
Товары = Новый Структура("Услуга");
Товары.Вставить("Услуга", НЕ ПечататьТолькоТовары);
Если ПечататьТолькоТовары Тогда
Выборка = Справочники.Номенклатура.ВыбратьИерархически( , , Товары);
Иначе
Выборка = Справочники.Номенклатура.ВыбратьИерархически();
КонецЕсли;
Пока Выборка.Следующий() Цикл
...
КонецЦикла;
Способ 2:
Если элемент выборки является услугой и стоит галочка «Печатать только товары», то не выводим элемент, а идем на следующий круг цикла.
Пока Выборка.Следующий() Цикл
Если Выборка.Услуга И ПечататьТолькоТовары Тогда
Продолжить;
КонецЕсли;
КонецЦикла;
т.к. процедура без контекста, то Сервер не понимает, что нарисовано в форме, поэтому в качестве второго параметра передадим значение реквизита формы «ПечататьТолькоТовары»:
&НаКлиенте
Процедура СформироватьПрайс(Команда)
ЗаполнитьТабДок(ТабДок, ПечататьТолькоТовары);
КонецПроцедуры
&НаСервереБезКонтекста
Процедура ЗаполнитьТабДок(ТабДок, ПечататьТолькоТовары)
...
КонецПроцедуры
В нашем примере первый способ не совсем корректен, т.к. в нем, если группа не является услугой, то система проигнорирует и группу и все подчиненные ей элементы. А в группе с признаком «Услуга – Ложь» все-таки могут располагаться элементы с признаком «Услуга - Истина».
Чтобы отобразить группу жирным, можно нарисовать строку для групп в макете и заполнять строку группы или элемента в зависимости от типа текущего элемента выборки в цикле:
Пока Выборка.Следующий() Цикл
...
Если Выборка.ЭтоГруппа Тогда
Обл = ОблГруппа;
Иначе
Обл = ОблЭлемент;
КонецЕсли;
Обл.Параметры.Заполнить(Выборка);
ТабДок.Вывести(Обл);
КонецЦикла;
А можно сделать это программно, не добавляя новой строки в макет:
«Шрифт» - это переменная, которая присваивается области макета.
Пока Выборка.Следующий() Цикл
...
ОблЭлемент.Параметры.Заполнить(Выборка);
ЖирныйШрифт = Новый Шрифт(,, Истина, Истина);
ОбычныйШрифт = Новый Шрифт(,, Ложь, Ложь);
ОблЭлементТекст = ОблЭлемент.Область("R1C2:R1C4");
Если Выборка.ЭтоГруппа Тогда
ОблЭлементТекст.Шрифт = ЖирныйШрифт;
Иначе
ОблЭлементТекст.Шрифт = ОбычныйШрифт;
КонецЕсли;
ТабДок.Вывести(ОблЭлемент);
Лучше создать для групп дополнительную область в макете, т.к. это менее трудоемко, чем задавать области в коде.
Итого:
Процедура ЗаполнитьТабДок(ТабДок, ПечататьТолькоТовары)
ТабДок.Очистить();
Макет = Отчеты.ПрайсЛист.ПолучитьМакет("Макет");
ОблШапка = Макет.ПолучитьОбласть("Шапка");
ОблЭлемент = Макет.ПолучитьОбласть("Элемент");
ОблГруппа = Макет.ПолучитьОбласть("Группа");
ОблШапка.Параметры.ДатаОтчета = Формат(ТекущаяДата(), "ДЛФ=DD");
ТабДок.Вывести(ОблШапка);
Пока Выборка.Следующий() Цикл
Если Выборка.Услуга И ПечататьТолькоТовары Тогда
Продолжить;
КонецЕсли;
ОблЭлемент.Параметры.Заполнить(Выборка);
Если Выборка.ЭтоГруппа Тогда
Обл = ОблГруппа;
Иначе
Обл = ОблЭлемент;
КонецЕсли;
Обл.Параметры.Заполнить(Выборка);
ТабДок.Вывести(Обл);
КонецЦикла;
КонецПроцедуры
Задача: сохранять справочные значения в виде истории. В примере – информацию о курсах валют.
Саму валюту будем хранить в справочнике:
Имя – Валюты.
Синоним – Валюты.
Представление объекта – Валюта.
Для хранения истории нельзя использовать реквизиты справочника, т.к. в них сохраняется только последнее значение.
Регистры сведений – хранят показатели учета:
Состояния.
Истории – может быть не только числовое значение, а, например, перечисление (например, метод списания – FIFO или LIFO, настроение – хорошее, плохое и т.д.). Если показатель характеризуется не числом, то это признак того, что его надо хранить в регистре сведений.
Какая таблица в системе должна быть создана для хранения курсов валют:
Ресурс – то, что храним в регистре.
Измерения – показатели, в разрезе которых хранится ресурс.
Периодичность регистра - если в разрезе измерения значение ресурса может с течением времени меняться.
Пример 1.Покупаем пластиковые игрушки разных цветов. Надо знать сколько игрушек определенного цвета есть:
Ресурс – цвета.
Измерение – игрушки.
А так как с течением времени цвет игрушки не меняется, то регистр будет «Непериодический».
Пример 2. Уровни доверия к контрагенту. Доверие с течением времени может изменяться например, от «не проверенный» до «надежный». Интересно сохранять историю данного показателя, значит регистр будет периодическим и у него будет поле «Дата».
Ресурс – надежность.
Измерение – контрагент.
Дата |
Валюта |
Курс |
Периодичность регистра |
Разрез измерения |
Ресурс |
Создадим регистр сведений:
Имя – КурсыВалют.
Синоним – Курсы валют.
Периодичность – В пределах дня.
Режим записи:
Независимый – можно вручную изменять значение ресурса. Есть только у регистра сведений. У остальных только значение «Подчинение регистратору».
Подчинение регистратору – формирование движений по регистру вручную невозможно.
В примере:
Режим записи – Независимый.
Основной отбор по периоду – будет ли в основной индекс включено поле «Период». Позволяет быстро искать значения в истории. Если чаще надо получать значения на настоящее время (последнее значение регистра), то галочку можно не ставить.
В примере:
Основной отбор по периоду – Истина.
Закладка «Данные»:
Измерения:
Валюта
Свойство |
Значение |
Имя |
Валюта |
Синоним |
Валюта |
Тип |
СправочникСсылка.Валюты |
Ведущее |
Истина |
Основной отбор |
Истина |
Запрет незаполненных значений |
Истина |
Запрет незаполненных значений – запрет записи пустых значений в регистр.
Основной отбор – поле «Валюта» попадет в основной отбор. Если «Основной отбор по периоду - Истина» и «Основной отбор - Истина», то в истории можно быстро получать значения в сочетании «Дата - Валюта».
Ведущее – сами значения, указанные в этом измерении владеют записями этого регистра. Допустим, при попытке удалить значение «Доллар» из справочника «Валюты»:
Если «Ведущее - Истина», то доллар удалится из справочника, а в регистре очистится история по нему.
Если «Ведущее - Ложь», то при система не даст удалить доллар из справочника, т.к. на него ссылаются записи регистра сведений, т.е. придется сначала очищать регистр, а потом уже удалять элемент справочника.
Ресурсы:
Курс
Свойство |
Значение |
Имя |
Курс |
Синоним |
Курс |
Тип |
Число 10,4 |
В режиме исполнения создадим несколько записей с курсами валют:
При попытке создать еще одну запись (с другим курсом) валюты USD на 02.01.12, система выдаст ошибку:
т.к. невозможно в регистр сведений записать значение с одинаковыми ключевыми полями (Период и Валюта)
В справочнике «Валюты» есть пункт «Перейти»:
При переходе по ссылке, откроется таблица регистра с установленным предопределенным отбором по валюте:
При создании новых элементов EUR будет автоматом браться из данных заполнения, т.к. отбор является данными заполнения:
Неотрицательное – лучше оставлять «Ложь», т.к. если будет введено отрицательное значение, то система не выдаст ошибки, а просто заменит его нулем, и на этапе отладки найти это значение будет тяжело. А когда уже все отлажено, то можно поставить «Истина».
Основное назначение регистра «Курсы валют» - получить значение курса определенной валюты на определенную дату.
У регистров сведений есть различные методы.
Допустим, установим курсы валюты на одну дату (1) и на другую дату (2), а надо найти курс на еще одну дату (3).
«Получить» - получим значение только на указанную дату (3) (если оно есть).
«ПолучитьПервое» - получим значение либо на указанную дату (3), либо на первое, которое встретится в будущем (2).
«ПолучитьПоследнее» - получим значение либо на указанную дату (3), либо на ближайшее значение в прошлом (1).
Т.к. курс валют используется в разных местах, то опишем универсальную процедуру (в общем модуле «ОбщиеМеханизмы»):
Валюта – валюта, курс которой получаем.
Дата – дата, на которую получаем курс.
«Дата = Неопределено» - дифференцированное значение – примет параметр, даже если он не будет передан.
Система получает параметр «Дата» по ссылке, опишем его как значение – «Знач Дата», чтобы разорвать связь с точкой вызова.
«ПолучитьПоследнее(<КонецПериода>, <Отбор>)» - у параметра «Отбор» тип – «Структура»:
Ключ – «Валюта».
Значение – «Валюта».
Функция ПолучитьКурсВалюты(Валюта, Знач Дата = Неопределено) Экспорт
Дата = ?(Дата = Неопределено, ТекущаяДата(), Дата);
Структура = Новый Структура;
Структура.Вставить("Валюта", Валюта);
Данные = РегистрыСведений.КурсыВалют.ПолучитьПоследнее(Дата, Структура);
Возврат Данные.Курс;
КонецФункции
«Возврат Данные.Курс» - знаем, что в данных есть курс т.к. метод «ПолучитьПоследнее» возвращает значение ресурса регистра сведений.
Если бы в регистре было два измерения, то надо было бы написать две строки структуры для отбора.
Пример:
В справочник «Контрагенты» добавим реквизит «Валюта взаиморасчетов» и при редактировании элемента справочника будем показывать текущий курс.
Реквизит «Валюта взаиморасчетов»:
Свойство |
Значение |
Имя |
ВалютаВзаиморасчетов |
Синоним |
Валюта взаиморасчетов |
Тип |
СправочникСсылка.Валюты |
В форме опишем поведение программы при выборе валюты взаиморасчетов:
Перетащим реквизит в форму. Добавим реквизит, не связанный с объектом:
Реквизит «Курс»
Свойство |
Значение |
Имя |
Курс |
Синоним |
Курс |
Тип |
Число 10, 4 |
Перетащим его в форму и назначим свойство:
Свойство |
Значение |
Вид |
Поле надписи |
чтобы пользователь не смог его поменять.
Моменты, когда курс должен отображаться:
1. Открытие формы существующего элемента, где валюта уже указана.
Процедура формы «ПриСозданииНаСервере()» - вызывается при создании формы на сервере, т.е. до отправки формы на Клиента.
2. При смене валюты взаиморасчетов.
Процедура реквизита «ВалютаВзаиморасчетов» «ПриИзменении()».
Одна процедура выполняется на Клиенте, а другая на Сервере, тогда процедура с логикой должна выполняться одновременно на Сервере и на Клиенте, т.е. вызвать ее можно будет и с сервера и с клиента:
&НаКлиентеНаСервереБезКонтекста
Процедура ОбновитьКурс(Валюта, Курс)
Если Валюта.Пустая() Тогда
Курс = 0;
Иначе
Курс = ОбщиеМеханизмы.ПолучитьКурсВалюты(Валюта);
КонецЕсли;
КонецПроцедуры
Будем вызывать эту процедуру из обеих процедур, передавая при этом как параметры значения Валюты и Курса, т.к. процедура выполняется без контекста.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ОбновитьКурс(Объект.ВалютаВзаиморасчетов, Курс);
КонецПроцедуры
&НаКлиенте
Процедура ВалютаВзаиморасчетовПриИзменении(Элемент)
ОбновитьКурс(Объект.ВалютаВзаиморасчетов, Курс);
КонецПроцедуры
