Лабораторная работа №3. Документы
Объект конфигурации Документ является прикладным и предназначен для описания информации о совершенных хозяйственных операциях или о событиях, произошедших в жизни организации вообще. На основе объекта конфигурации Документ платформа создает в базе данных информационную структуру, в которой будут храниться, например, такие документы, как приходные накладные, или приказы о приеме на работу, или платежные поручения, или счета и т. д.
Характерной особенностью объекта конфигурации Документ является то, что в процессе работы пользователь может самостоятельно создавать новые объекты этой структуры - новые документы.
Свойства документа отличается от свойств всех остальных объектов базы данных. Документ обладает способностью проведения. Факт проведения документа означает, что событие, которое он отражает, повлияло на состояние учета. До тех пор, пока документ не проведен, состояние учета неизменно, и документ – не более чем черновик, заготовка. Как только документ будет проведен – изменения, вносимые документом в учет, могут вступить в силу и состояние учета может быть изменено.
Поскольку документ вносит изменения в состояние учета, он всегда «привязан» к конкретному моменту времени. Это позволяет отражать в базе данных фактическую последовательность событий.
Следующим важным фактом, вытекающим из двух предыдущих, является то, что система 1С:Предприятие имеет механизмы, позволяющие отслеживать правильность состояния учета. Предположим, что мы изменили один из проведенных ранее документов и снова провели его «задним числом». В этом случае система 1С:Предприятие способна отследить, повлияют ли внесенные нами изменения на последующие проведенные документы, и если это так, система способна перепровести необходимые документы.
Каждый документ, как правило, содержит информацию, которая подробнее описывает этот документ. Например, каждый документ ПриходнаяНакладная может содержать информацию о поставщике товаров, складе, на который приходуется товар, и т. д. Набор такой информации является одинаковым для всех документов одного вида, и для описания такого набора используются реквизиты объекта конфигурации Документ, являющиеся подчиненными объектами конфигурации. Большинство реквизитов объекта конфигурации Документ разработчик создает самостоятельно, однако у каждого объекта конфигурации Документ существуют два поля «по умолчанию»: Дата и Номер документа. Поскольку тип данных Дата содержит дату и время с точностью до секунды, этот реквизит и определяет в основном положение документа на оси времени.
Кроме этого, каждый документ содержит, как правило, некоторый набор информации, которая одинакова по своей структуре, но различна по количеству, предназначена для разных документов. Так, например, каждый документ ПриходнаяНакладная может содержать список приходуемых товаров. Для описания подобной информации служат табличные части объекта конфигурации Документ.
Для «визуализации» документа существует несколько основных форм.
Факт проведения документа и необходимость поддержания актуальной последовательности документов на оси событий порождают два различных способа проведения документов: оперативное и неоперативное проведение.
С оперативным проведением документов связано понятие оперативной отметки времени.
Оперативная отметка времени представляет собой значение типа Дата, которое формирует система. Оперативная отметка времени создается системой каждый раз при оперативном проведении документа. Ее значение формируется исходя из текущего времени и последней созданной оперативной отметки.
Если последняя оперативная отметка меньше текущего времени, в качестве новой оперативной отметки принимается текущее время.
Если последняя оперативная отметка равна или больше текущего времени, в качестве новой оперативной отметки принимается значение на одну секунду большее, чем старая оперативная отметка времени.
Таким образом, если у объекта конфигурации Документ установлено свойство оперативного проведения, последовательность действий системы будет следующей: при создании нового документа система будет устанавливать ему текущую дату и «нулевое» время.
При проведении такого документа (с текущей датой) система установит в качестве даты документа оперативную отметку времени. Если отменить проведение документа и затем провести его снова (не изменяя даты), система установит документу новую оперативную отметку времени.
Если же попытаться перепровести документ, то будет выдан запрос о виде проведения (оперативное или нет).
В случае оперативного проведения система установит новую оперативную отметку времени, а при неоперативном проведении время документа будет сохранено прежним.
При попытке проведения (или перепроведения) оперативно проводимого документа с датой, отличающейся от текущей, будет выдано сообщение о том, что оперативное проведение невозможно, и предложено провести документ неоперативно (то есть с сохранением существующей даты и времени документа).
Прежде чем мы приступим к практическому созданию документов, необходимо сделать отступление о том, какие типы данных могут использоваться в системе 1С:Предприятие.
В предыдущей главе, когда мы создавали реквизиты справочников или табличных частей, мы всегда указывали тип значения, которое может принимать этот реквизит. Это были примитивные типы данных: Число, Строка, Дата и Булево. Примитивные типы данных изначально определены в системе и их набор ограничен.
Наряду с такими изначально определенными в любой конфигурации типами могут существовать типы данных, определяемые только конкретной конфигурацией. Такие типы сами образуют объекты конфигурации в момент их создания в конфигураторе.
Например, после того, как мы создали объект конфигурации Справочник Склады, сразу же появилось несколько новых типов данных, связанных с этим справочником. Среди них, например, СправочникСсылка.Склады. И если теперь мы укажем какому-либо реквизиту этот тип данных, то сможем хранить в нем ссылку на конкретный объект справочника Склады.
Объекты конфигурации, которые могут образовывать новые типы данных, называются типообразующими.
Это небольшое отступление было необходимо потому, что уже при создании первого документа мы столкнемся с использованием типа данных, доступным благодаря объекту конфигурации Справочник Склады.
После того, как мы познакомились с объектом конфигурации Документ, создадим несколько таких объектов, чтобы иметь возможность фиксировать события, происходящие в нашем ООО «Компьютер-сервис».
Одними из самых популярных услуг нашего предприятия является ремонт компьютеров и заправка картриджей. И в том, и в другом случае требуются некоторые материалы, которые расходуются в процессе оказания этих услуг. Поэтому двумя важнейшими событиями в хозяйственной жизни нашей организации будут являться поступление материалов и оказание услуг.
Для отражения этих событий в базе данных мы создадим два документа: Приходная накладная и Оказание услуги. Документ ПриходнаяНакладная будет фиксировать факт поступления в нашу организацию необходимых материалов, а документ ОказаниеУслуги – фиксировать оказание услуг и расход материалов, которые используются при оказании этих услуг.
Откроем конфигуратор и добавим новый объект конфигурации Документ. На закладке Основные зададим имя документа - ПриходнаяНакладная. На основании имени платформа автоматически заполнит его синоним.
Здесь же определим, как будет представлен документ в интерфейсе 1С Предприятия. Представление объекта задавать не будем, вместо него будет использоваться Синоним объекта. Это нам вполне подходит, так как мы задали его имя в единственном числе.
Представление списка, наоборот, зададим во множественном числе как Приходные накладные.
Нажмем Далее и перейдем на закладку Подсистемы.
По логике нашей конфигурации список приходных накладных должен быть доступен в разделах Учет материалов и Бухгалтерия.
Перейдем на закладку Данные и создадим реквизит документа именем Склад. Для этого нажмем кнопку Добавить над списком реквизитов документа.
Выберем для реквизита ссылочный тип данных СправочникСсылка.Склады. Этот тип стал доступен в конфигурации после создания объекта конфигурации Справочник Склады.
Теперь покажем, как можно облегчить «жизнь» пользователя при приходовании материалов. Работа в автоматизируемой нами фирме построена таким образом, что, как правило, все поступающие товары приходуются на основной склад.
Поэтому в палитре свойств для созданного нами реквизита Склад документа найдем свойство Значение заполнения.
В качестве значения этого свойства выберем предопределенный элемент справочника Склады - Основной.
После этого добавим в документ табличную часть с именем Материалы.
Создадим реквизиты табличной части Материалы:
■ Материал, тип СправочникСсылка. Номенклатура;
■ Количество, тип Число, длина 15, точность 3, неотрицательное;
■ Цена, тип Число, длина 15, точность 2, неотрицательное;
■ Сумма, тип Число, длина 15, точность 2, неотрицательное.
В заключение отредактируем командный интерфейс, чтобы в подсистеме Учет материалов была доступна команда создания новых документов.
Для этого в дереве объектов конфигурации выделим ветвь Подсистемы, вызовем ее контекстное меню и выберем пункт Все подсистемы. В открывшемся окне слева в списке Подсистемы выделим подсистему УчетМатериалов.
Справа в списке Командный интерфейс отразятся все команды выбранной подсистемы.
В группе Панель действий.Создать включим видимость у команды Приходная накладная: создать.
Запустим 1С:Предприятие в режиме отладки и протестируем получившийся документ.
Пока в нашей базе данных нет ни одного документа Приходная накладная, поэтому выполним команду Приходная накладная в панели действий раздела Учет материалов и создадим новую приходную накладную.
Перед нами откроется форма документа - основная форма объекта. Заголовок этой формы Приходная накладная совпадает с синонимом документа.
Система автоматически подставит текущую дату создания документа и нулевое время, так как документ еще не проведен. В качестве времени документа при оперативном проведении ему присваивается оперативная отметка времени.
Поле Номер не заполнено, но система сама сгенерирует для нового документа уникальный номер, так как свойство Автонумерация для документа включено по умолчанию. Новый номер будет сохранен в момент записи документа.
Обратите внимание, что склад уже заполнен значением Основной, как мы и задали в свойствах этого реквизита.
Нам осталось только заполнить табличную часть приходной накладной материалами для ремонта телевизоров так, как показано на рисунке.
Нажмем Провести и закрыть.
Документ будет сохранен и проведен, ему будет присвоен автоматически сгенерированный системой номер и текущее время проведения документа.
Аналогичным образом мы создадим второй документ, который будет приходовать на Основной склад материалы для ремонта системных блоков. Но теперь не будем использовать кнопку выбора в поле Материал, а просто начнем вводить название материала в это поле. Платформа автоматически найдет материалы, наименование которых начинается с введенных нами символов, и предложит их нам для выбора.
Нажмем Провести и закрыть.
Документ будет сохранен и проведен, ему будет присвоен автоматически сгенерированный системой номер и текущее время проведения документа.
Чтобы просмотреть список созданных документов, выполним команду Приходные накладные в панели навигации.
Наверняка вы обратили внимание на то, что при заполнении документа приходится вводить сумму в каждой строке. Это неудобно, и возникает естественное желание автоматизировать работу документа так, чтобы сумма вычислялась автоматически каждый раз при изменении цены или количества материалов в строке.
Это совсем не сложно, и для этого нам потребуется сначала создать собственную форму документа, а затем воспользоваться возможностями встроенного языка.
Дело в том, что до сих пор мы использовали предопределенные формы объектов, которые система 1С:Предприятие по умолчанию создавала для нас сама. Теперь же у нас возникла необходимость слегка изменить логику работы формы документа, поэтому нам нужно создать свою собственную форму документа ПриходнаяНакладная для того, чтобы в ней с помощью встроенного языка описать тот алгоритм, который нам нужен. И система будет использовать нашу форму вместо формы по умолчанию.
Вернемся в конфигуратор и откроем окно редактирования объекта конфигурации Документ ПриходнаяНакладная.
В этом окне нас интересует закладка Формы.
Как мы видим, ни одна из основных форм документа пока не задана. Для того чтобы создать форму документа, нажмем кнопку открытия со значком лупы в поле ввода или кнопку Добавить над списком форм. Система вызовет еще один полезный инструмент разработчика - Конструктор форм.
Выберем тип формы Форма документа и нажмем кнопку Готово, согласившись тем самым со всем, что нам предложила система.
Итак, нас интересуют три элемента табличной части: МатериалыКоличество, МатериалыЦена и МатериалыСумма.
Мы хотим, чтобы каждый раз, когда меняется значение в поле Количество или в поле Цена, в поле Сумма автоматически устанавливалось значение, равное Количество*Цена.
Очевидно, что для этого нужно написать на встроенном языке команду, похожую на Сумма = Количество*Цена, которая будет выполняться при изменении значения поля Количество или Цена. Но как «поймать» эти моменты изменения?
Очевидно, что нам нужно событие ПриИзменении, которое возникает после изменения значения поля. Найдем его в списке событий и нажмем кнопку открытия со значком лупы в поле ввода.
Система создаст шаблон процедуры обработчика этого события в модуле нашей формы и откроет закладку Модуль редактора формы.
Модуль - это «хранилище» для текста программы на встроенном языке. В данном случае это модуль формы, так как обработчики всех интерактивных событий, связанных с элементами формы, помещаются именно в модуль формы.
В модуль формы, в процедуру МатериалыКоличествоПриИзменении(), мы и добавим следующий текст:
СтрокаТабличнойЧасти.Сумма = СтрокаТабличнойЧасти.Количество * СтрокаТабличнойЧасти.Цена;
Объясним назначение этих строк.
В первой строке мы сначала создаем переменную СтрокаТабличнойЧасти, в которую будет помещен объект, содержащий данные, находящиеся в строке табличной части, которую нам нужно пересчитать.
Мягкая типизация данных встроенного языка позволяет сделать это, не объявляя переменную и ее тип заранее. Мы создаем переменную прямо по ходу работы, и ее тип определяется типом значения, которое она содержит.
Поскольку мы находимся в модуле формы, то в нем доступны все свойства и методы объекта встроенного языка УправляемаяФорма. Поэтому мы можем обращаться к ним напрямую. В данном случае после знака равенства мы обращаемся к коллекции элементов формы, используя одно из свойств объекта УправляемаяФорма - свойство Элементы.
Коллекция элементов формы является объектом встроенного языка ВсеЭлементыФормы, содержащим все элементы формы. То есть это программный аналог корня дерева элементов формы.
Каждый элемент формы можно получить, указав его имя в качестве свойства этого объекта, то есть через точку от него. В данном случае мы обращаемся к табличной части документа Материалы (Элементы.Материалы).
Табличная часть документа представляет собой объект встроенного зыка ТаблицаФормы. Получить ту строку, в которой в настоящее время осуществляется редактирование, можно при помощи свойства программного объекта ТаблицаФормы - ТекущиеДанные Элементы.Материалы.ТекущиеДанные).
Таким образом, в результате выполнения первой строки процедуры обработчика переменная СтрокаТабличнойЧасти будет содержать объект ДанныеФормыСтруктура. Этот объект содержит данные, находящиеся в текущей строке табличной части документа (Элементы. Материалы.ТекущиеДанные).
Получив этот объект, мы можем обратиться к данным конкретной колонки табличной части, указав имя колонки в качестве свойства объекта. Например, используя обращение СтрокаТабличнойЧасти.Количество мы получаем число, которое находится в редактируемой строке в колонке Количество.
Таким образом, во второй строке процедуры обработчика вычисляется значение колонки Сумма как произведение значений колонок Количество и Цена.
Теперь посмотрим, как это работает. Запустим 1С:Предприятие в режиме отладки, откроем список документов Приходные накладные и откроем любой из двух созданных нами документов. Если теперь вы поменяете количество в любой строке документа, то сумма в строке будет пересчитана автоматически.
Итак, мы убедились, что при изменении количества в любой строке документа Приходная накладная, сумма в этой строке пересчитывается автоматически.
Замечательно. Но теперь хотелось бы и для поля Цена сделать то же самое. А если заглянуть вперед, то мы увидим, что подобное автоматическое заполнение поля Сумма может нам понадобиться и в других документах.
Поэтому лучше будет поместить расчет суммы в некоторое «общедоступное» место, чтобы разные документы, имеющие аналогичные реквизиты табличной части, могли использовать этот алгоритм.
Для описания таких «общедоступных» мест служат объекты конфигурации Общий модуль, расположенные в ветке Общие - Общие модули. Процедуры и функции, содержащиеся в этих модулях, могут быть доступны для любых объектов конфигурации.
Поэтому создадим общий модуль и перенесем в него нашу процедуру расчета суммы. А в документе просто оставим вызовы этой процедуры из общего модуля.
Добавим объект конфигурации Общий модуль.
Для этого раскроем ветвь Общие в дереве объектов конфигурации, нажав на + слева от нее. Затем выделим ветвь Общие модули и нажмем кнопку Добавить в командной панели окна конфигурации.
Назовем его РаботаСДокументами и установим в его свойствах флажок Клиент (управляемое приложение), а флажок Сервер снимем. Это означает, что экземпляры этого модуля будут скомпилированы в контексте тонкого клиента и в контексте веб-клиента.
Внесем в модуль следующий текст:
Прокомментируем этот код. В процедуру РассчитатьСумму() мы передаем переменную СтрокаТабличнойЧасти, которую мы определили в обработчике события ПриИзменении поля Количество. Она содержит данные редактируемой строки табличной части документа ПриходнаяНакладная.
Теперь, используя эту переменную, мы можем получить доступ к данным колонок табличной части и рассчитать сумму как произведение цены на количество.
Ключевое слово Экспорт в заголовке процедуры указывает на то, что эта процедура может быть доступна из других программных модулей.
Теперь в модуле нашей формы изменим текст обработчика.
Мы видим, что первая строка процедуры осталась без изменений. А во второй строке вместо непосредственного расчета суммы мы вызываем процедуру РассчитатьСумму() из общего модуля РаботаСДокументами и передаем ей в качестве параметра текущую строку табличной части.
Проверим, как это работает, и убедимся, что ничего не изменилось.
Теперь осталось и для поля Цена установить такой же обработчик.
Создадим обработчик события ПриИзменении для поля табличной части МатериалыЦена так же, как мы делали это для поля МатериалыКоличество, и повторим в нем вызов процедуры РассчитатьСумму() из общего модуля.
Запустим 1С Предприятие в режиме отладки и убедимся, что теперь сумма в строках табличной части документов ПриходнаяНакладная пересчитывается как при изменении количества, так и при изменении цены.
1) Создать документ Оказание услуги (подсистемы Оказание услуг и Бухгалтерия). Реквизиты документа: Склад, клиент, мастер, табличная часть ПереченьНоменклатуры с реквизитами: номенклатура, количество, цена, сумма.
2)Создать форму документа Оказание услуги и написать в ней процедуры для автоматического расчета суммы аналогично документу Приходная накладная.
3) В режиме 1С: Предприятие создать и провести несколько документов по оказанию услуг.