записать объект в форме 1с управляемые формы
Для понимания особенностей записи и проведения документа в форме следует, прежде всего, разделять особенности записи самого объекта (ДокументОбъект) и особенности работы расширения формы. Расширение формы документа действует, если основной реквизит формы имеет тип ДокументОбъект. Оно обеспечивает специфическую функциональность формы при редактировании и записи документа. Задача расширения заключается в реализации удобного для пользователя поведения формы. Но собственно запись и проведение документа выполняет, разумеется, объект, являющийся реквизитом формы. Расширение документа обрабатывает различные команды пользователя, выполняет предварительные проверки и другие сервисные действия, а затем вызывает запись объекта. Запись объекта выполняется так же, как и если бы она вызывалась средствами встроенного языка. То есть с точки зрения объекта запись в форме и запись средствами языка ничем не различаются. Таким образом, расширение обеспечивает некоторую сервисную функциональность, обращаясь в конечном итоге к функциональности объекта. Следует учитывать, что расширение формы действует, только если используются механизмы формы и не действует, если выполняется обращение непосредственно к объекту. Например, если вызвать метод Записать() у объекта ДокументОбъект, то никакие действия расширения формы не будут выполняться. Чтобы они выполнялись нужно вызывать метод ЗаписатьВФорме().
Далее мы рассмотрим те сервисные действия, которые обеспечивает расширение формы документа. В данном разделе, мы опишем только те действия, которые специфичны именно для расширения формы документа и не будем касаться общих действий, которые поддерживаются расширениями всех объектов.
Установка даты документа
При открытии формы нового документа, если дата документа не установлена (равна значению типа Дата по умолчанию), то документу устанавливается рабочая дата. Следует заметить, что используется именно рабочая дата, а не текущая (если не установлено использование текущей даты в качестве рабочей). Это дает возможность пользователю настроить рабочую дату так, чтобы новые документы вводились определенной датой. При этом в качестве даты устанавливается начало дня (дата без времени), даже если в качестве рабочей даты выступает текущая дата. Но если свойство АвтоВремя имеет значение НеИспользовать, и рабочая дата равна текущей, то устанавливается текущая дата, вместе со временем. Таким образом, для варианта АвтоВремя = НеИспользовать при открытии берется рабочая дата (если она отличается от текущей) или текущая дата вместе со временем, а для остальных вариантов установка времени откладывается на момент записи документа.
При записи нового документа в форме если свойство АвтоВремя имеет значение отличное от НеИспользовать, и не используется оперативное проведение, и время документа пустое (0:00:00), то выполняется автоматическая установка времени на основании значения свойства АвтоВремя. Действие расширения формы в этом случае аналогично вызову метода УстановитьВремя() с вариантом выбранном в свойстве АвтоВремя и с использованием журналов документа.
Расширение формы так же предоставляет команды для установки времени документа в начало дня, конец дня, перед предыдущим и за последующим документом.
Установка режима записи
При нажатии кнопки «ОК», если для документа в метаданных разрешено проведение, документ записывается в режиме проведения.
Кроме того, расширение формы предоставляет две отдельные команды для записи с проведением и записи с отменой проведения.
При любой записи документа в форме, если установлено свойство расширения формы ПриЗаписиПерепроводить и документ проведен, то выполняется запись в режиме проведения. Это позволяет исключить ситуацию, когда пользователь изменит документ, а движения документа не будут обновлены.
Установка режима оперативного проведения
При записи документа в форме, расширение формы выполняет установку режима проведения (оперативное или неоперативное проведение). Установка выполняется по следующему алгоритму.
Вначале если свойство ИспользоватьРежимПроведения имеет значение Авто выполняется первичный подбор режима проведения из вариантов Оперативный, Неоперативный и Запрашивать.
Если у пользователя нет права на неоперативное проведение – используется оперативное проведение.
Если документ не проведен – используется оперативное проведение.
Если дата документа равна текущей, а время меньше или равно текущему, то используется режим Запрашивать. Здесь и далее в этой статье сравнение даты имеется в виду без учета времени, а сравнение времени описывается отдельно.
Если дата документа меньше текущей, то используется неоперативное проведение.
Если дата документа равна текущей и время больше текущего – используется оперативное проведение.
Дальнейшие действия системы определяются уже исходя из трех вариантов (Оперативный, Неоперативный и Запрашивать) установленных непосредственно в свойстве ИспользоватьРежимПроведения или на основании описанного алгоритма для варианта Авто.
Если дата документа меньше текущей, используется оперативный режим и у пользователя есть права на неоперативное проведение, то пользователю предлагается использовать неоперативный режим. Если пользователь отказывается, то запись документа отменяется.
Если дата документа меньше текущей, используется оперативный режим и у пользователя нет права на неоперативное проведение, то запись документа отменяется.
Если дата документа меньше текущей и используется режим Запрашивать, то в зависимости от наличия прав на неоперативное проведение или выбирается неоперативный режим (без запроса пользователя), или запись документа отменяется.
Если дата документа больше текущей и используется оперативный режим, то запись документа отменяется. Штатное поведение расширения формы не разрешает проведение документа завтрашней датой, даже если у пользователя есть права на неоперативное проведение. Это объясняется тем, что после появления документов проведенных завтрашней датой текущие остатки регистров используемых проводимыми оперативно документами перестают соответствовать реальным остаткам и механизм оперативного проведения для всех пользователей перестает работать адекватно.
Далее если используется режим Запрашивать, то пользователю выдается диалог с выбором режима проведения.
Полученный таким образом режим проведения (Оперативный или Неоперативный) используется при выполнении записи документа.
Проверка прав
При открытии формы документа, если документ проведен, а у пользователя нет права «Интерактивное изменение проведенных», то расширение переводит форму в режим ТолькоПросмотр.
При записи документа в форме выполняется проверка прав на интерактивное проведение и интерактивную отмену проведения в соответствии с текущим режимом записи.
Считывание движений
При открытии формы документа, если есть табличные поля, связанные с движениями (наборами записей) объекта редактируемого в форме, то эти движения считываются из базы данных и соответственно отображаются в табличных полях.
Запись объекта из модуля формы
Короче я в модуле формы справочника.
У него основной реквизит СправочникОбъект.
Далее хочу изменить некоторые данные объекта.
Если меняю непосредственно в БД, то ошибка о несоответсвии форме.
Правильно как менять, передать СправочникОбъект через ДанныеФормыВ значение, изменить, вернуть через ЗначениеВДанныеФормы и далее записать форму, это должно поместить всё данные в БД? или надо было записать объект до ЗначениеВДанныеФормы
Так а когда форма открыта, она знает только ссылку на свой объект.
Когда я делаю ДанныеФормыВЗначение(Объект, Тип) что происходит, то же что и при Объект.Ссылка.ПолучитьОбъект()?
После определенные манипуляции с объектом и могу вернуть обновленное состояние с помощью ЗначениеВДанныеФормы, либо ОбновитьОтображениеДанных примерно то же сделает?
Вроде всё получилось, так для понимания разницы спрашиваю, как правильнее
в общем я могу с формы на сервере менять её объект напрямую и запись формы будет эквивалентна записи объекта в БД
(8) да кстати процедурку в модуле объекта хочу вызвать, значит в этом случае через ДанныеФормыВЗначение
Че-то ты там мутишь.
Запись формы это не то же самое что запись объекта. Ну то есть, при записи формы с основным реквизитом, конечно, произойдет запись объекта (при этом того экземпляра объекта, который подразумевается основным реквизитом, а не какого-нибудь левого экземпляра, который ты мог получить хз где), но не наоборот. Ну плюс в форме при записи еще может много чего происходить чего не происходит при записи объекта.
Если запишешь объект справочника, данные объекта лягут в БД, но форма про это ничего знать не будет (пока не попытаешься записать эту форму и она не заругается).
Если запишешь форму справочника, данные объекта из формы лягут в БД, но про это ничего не узнает твоя переменная с объектом справочника.
Если хочешь синхронизировать форму справочника или объект справочника с данными из БД, то есть метод Прочитать (а в форме еще выполнится ПриЧтенииНаСервере и все такое).
Если хочешь синхронизировать реквизит формы с объектом справочника, то есть ЗначениеВРеквизитФормы или там ЗначениеВДанныеФормы.
Базовый принцип программирования управляемой формы в 1С
Цель статьи – показать применение шаблонов Remote Facade и Data Transfer Object к структуризации кода, управляемой формы в среде 1С 8.2.
Введение
Начнем с небольшого описания понятия «управляемая форма» и связанных концепций платформы 1С. Знатоки платформы могут пропустить этот раздел.
Все дальнейшие рассуждения будут о правой части иллюстрации, о том, как структурировать код модуля и какие принципы позволят реализовать эффективное клиент-серверное взаимодействие.
Обозначим проблему
Прошло уже несколько лет как новая версия платформы 1С активно используется и выпущено множество решений (конфигураций) как фирмой 1С, так и ее многочисленными партнерами.
Сложилось ли за это время у разработчиков единое понимание принципов клиент-серверного взаимодействия при создании форм, и изменился ли подход к реализации программных модулей в новых архитектурных реалиях?
Рассмотрим структуру кода (модуль формы) в нескольких формах одной типовой конфигурации и попробуем найти закономерности.
Под структурой будем понимать секции кода (чаще всего это блоки комментариев) выделенные разработчиком для группировки методов и директивы компиляции этих методов.
Пример 1:
Зачем нужна структура кода?
Почему существующий стандарт разработки от фирмы 1С не помогает?
Шаблоны проектирования или мудрость поколений
Примеры шаблонов в платформе 1С
Прикладной программный интерфейс доступный разработчику при разработке управляемой формы, содержит много примеров данных принципов.
Например метод ОткрытьФорму(), типичный «огрубленный» интерфейс.
Сравните с принятым в v8.1 стилем.
Структурируем код
Записать объект в форме 1с управляемые формы
Довольно часто встречаются задачи, когда нужно организовать программное заполнение формы какого-то объекта. Скажем, у нас есть форма документа, на форме есть реквизиты, и нам нужно сделать команду, которая заполнит эти реквизиты. Данные для заполнения предполагается получать запросом.
Если конфигурация типовая, то, наверное, самый простой способ решения такой задачи – создать внешнюю обработку вида «Заполнение объекта».
Заполнение формы объекта с помощью внешней обработки
Строка с соответствующим параметром в модуле обработки:
Подключив обработку и указав, для какого документа она назначена, мы получим в форме документа команду. Тип команды задаётся при создании внешней обработки, и от него зависит, где и как будет выполняться обработчик команды. Для наших целей может подойти один из следующих типов команд:
Возможность заполнить форму не записывая объект – это то, что нужно. Ведь пользователь скорее всего ожидает, что по нажатию кнопки форма заполнится, а записываться будет позднее, после проверки результата заполнения. Поэтому выбираем тип команды – ЗаполнениеФормы.
В конечном итоге код в модуле обработки будет выглядеть примерно так:
В общем счёте задача решена. Однако, у такого способа есть небольшой недостаток – команда на форме размещается в определённом месте, а не там, где мы хотим её разместить. К примеру, на форме уже есть группа команд, включающая в себя команды заполнения, и мы хотели бы видеть новую команду в этой группе, но при подключении обработки команда на форме будет расположена отдельно от группы.
В связи с этим можно реализовать другой способ: добавить команду непосредственно в форму объекта – либо в основной конфигурации, либо в расширении – а обработчик команды организовать в модуле формы.
Заполнение формы объекта посредством обработчика команды в модуле формы
Итак, размещаем команду на форме объекта в том месте, которое нам нравится. В модуле формы добавляем клиентскую процедуру обработчика команды, из которой будем вызывать серверную процедуру. Серверную процедуру тоже создадим, она нам понадобится потому, что по условию задачи данные для заполнения получаются запросом.
Над серверной процедурой нужно подумать. В ней у нас будет объект формы с типом «ДанныеФормыСтуктура». Что-либо менять или заполнять в этом объекте не получится, возникнет ошибка «Объект недоступен для изменения».
Вот теперь и форма заполнена, и кнопка команды там, где хочется.
Программирование в 1С для всех
В этой статье научимся приемами программного создания и заполнения документов в 1С 8.3, кроме того, мы узнаем, как программно записывать и проводить документ 1С, а также узнаем, как программно открыть основную форму документа.
Прежде чем мы начнем разбирать вопросы программной работы с документами в 1С 8.3, хочу обратить Ваше внимание, что на управляемой форме в режиме тонкого клиента мы можем программно работать (создавать, записывать и проводить) с документами только в серверном контексте. То есть, ваша процедура или функция должна выполняться под директивами &НаСервере или &НаСервереБезКонтекста.
Все примеры в этой статье я буду показывать на управляемой форме обработки, которую создал «за кадром».
Создать документ 1С программно
В моей учебной конфигурации 1С имеется простенький документ с небольшим набором реквизитов, а также с одной табличной частью.
Для этой команды, я сделаю обработчики на клиенте и на сервере.
В серверном обработчике мы и напишем код, который и будет создавать документ..
В этом коде я обратился к менеджеру документа ПриходТовара (строка Документы.ПриходТовара), и использовал функцию менеджера документа СоздатьДокумент, которая и создает документ-объект. Переменная ДокПриход, которую мы создали будет иметь тип ДокументОбъект.ПриходТовара.
Следующим шагом, я присвою дату этому документу, для простоты, это будет текущая дата.
Номер я присваивать не буду, потому что у объекта моего документа включено свойство Автонумерация.
В принципе, этого вполне достаточно, чтобы наш документ существовал. Но создав его при помощи функции СоздатьДокумент, мы не записали его непосредственно в базу. После выполнения кода выше, ни какого документа в базе не появится!
Записать документ 1С программно
Для того, чтобы документ 1С появился в базе, его необходимо записать. Делается это при помощи метода документа-объекта Записать. Этот метод позволяет и записать, и провести документ. Он имеет два параметра, которые я разберу ниже. Но, метод Записать также можно использовать и без параметров, тогда он будет просто записывать документ. Что мы и сделаем.
Все теперь документ появится в базе.
Мы его можем создать, и это будет абсолютно пустой документ, без всяких реквизитов и без заполненной табличной частью.
Для того, чтобы что-то в нем появилось, нам необходимо заполнить этот документ.
Заполнить документ 1С программно
У нашего документа два реквизита «шапки» – Склад и Комментарий. Создадим на форме обработки реквизит управляемой формы Склад с соответствующим типом, для последующей записи его в шапку документа, а реквизит комментарий заполним в ручную.
Присвоим реквизитам созданного объекта-документа нужные значения, просто обратившись через точку к этим реквизитам.
Так мы заполнили реквизиты «шапки», но у нас имеется еще табличная часть документа, необходимо заполнить и её. Для её заполнения, я создам таблицу значений в качестве реквизита формы обработки, и помещу её на эту форму.
Мы будем в цикле обходить эту таблицу значений, создавая в каждой итерации цикла новую строку табличной части документа и заполняя её данными.
В этом коде я обращаюсь к табличной части документа-объекта посредством точки (строка ДокПриход.СписокТоваров), получаю табличную часть этого объекта, и используя метод Добавить, создаю новую строку табличной части. А потом заполняю реквизиты табличной части документа данными из таблицы значений. Поскольку у нас названия реквизитов табличной части и таблицы значений совпадают, мы можем упростить код заполнения табличной части, используя метод ЗаполнитьЗначенияСвойств.
Всё! Мы можем смело создать документ, который будет заполнен.
Провести документ 1С программно
Все документы, которые мы создавали ранее были не проведены. Если мы хотим, чтобы документ был записан проведенным, то необходимо записывать его немного по-другому. Если раньше мы использовали метод Записать объекта документа без параметров, то теперь необходимо применять параметры этого метода. Данный метод имеет следующий синтаксис.
Записать( , )
Оба параметра это системные перечисления. Первый параметр это перечисление РежимЗаписиДокумента, которое может принимать следующие значения:
Т.е. мы можем записать документ, провести документ и отменить проведение документа.
Во втором параметр РежимПроведения необходимо указывать системное перечисление РежимПроведениеДокумента, которое может принимать следующие значения:
Т.е. мы можем провести документ как в оперативном режиме, так и в неоперативном. Если этот параметр не указан, то документ проводится в неоперативном режиме.
Изменим запись нашего документа: пусть он проводится в оперативном режиме.
Теперь документ будет сразу проведен при создании.
Изменить документ 1С программно
Часто возникают задачи, когда нужно поменять уже созданный документ, или провести документ, который был только записан. Для этого необходимо из ссылки на документ получить его объект. Для примера, я опять создам «за кадром» новую обработку, на форме которой размещу ссылку на документ, поле с типом Склад и команду. При выполнение этой команды, будет меняться склад документа, а потом этот документ будет проводиться.
Как и в прошлый раз, я создам обработчик команды на сервере и на клиенте. И в серверном обработчике напишу код получения объекта из ссылки документа.
Мы получили объект документа, используя метод ссылки на документ ПолучитьОбъект. Имейте в виду, что этот метод можно использовать или на сервере, или клиенте в режиме толстого клиента. Переменная, которую мы создали будет иметь тип ДокументОбъект.ПриходТовара.
Изменим склад и проведем документ. В этот раз проведем в неоперативном режиме.
Открыть документ 1С программно
Научимся открывать документ 1С программно. Для этого мы доработаем предыдущую обработку: после изменения документа откроем основную форму этого объекта для просмотра и возможного редактирования. Для открытия формы документа, мы будем использовать метод ОткрытьФорму, в котором будем использовать параметр Ключ, где укажем ссылку на открываемый документ.
Если мы сейчас выполним этот код, то откроется форма документа, с уже измененным реквизитом Склад.
Более подробно и основательно разработка в 1С дается в моей книге: «Программировать в 1С за 11 шагов»
Изучайте программирование в 1С в месте с моей книги «Программировать в 1С за 11 шагов»
О том как разрабатывать под управляемым приложением 1С, читайте в книге Книга «Основы разработки в 1С: Такси»
Отличное пособие по разработке в управляемом приложении 1С, как для начинающих разработчиков, так и для опытных программистов.
Промо-код на скидку в 15% — 48PVXHeYu
Вступайте в мои группы:
6 thoughts on “ Программная работа с документами в 1С ”
Одинаковые имена для реквизитов и элементов — это норма. Любую типовую открой и посмотри, как там сделано.
И о какой ошибке округления идет речь? Ты что здесь округлять собрался? В момент записи значения в поле Сумма округление производится автоматически в соответствие с заданной точностью в Конфигураторе.
По поводу книг. Читал книгу «Программировать в 1С за 11 шагов», книга написана очень понятным и доступным языком. Это первая книга, читая которую, я начал что-то понимать в 1С.
Ильяс, спасибо за статью. Что касается падежей — это не самое страшное. Плохо то, что сразу нарисовываются какие — то «умники», которых будут волновать округления и падежи. А вот если бы в статье о программной работе с документами учитывались округления, попытки, исключения — это была бы действительно статья типичного 1С — ника, которых полно и толку от которой — ноль. Не обращай на таких внимания. Основная масса, к сожалению, такая.
Падежи можно, конечно, и пропустить. Хотя, лучше все эти склонения и жиши перепроверить. Читающие оценят. Однако, ошибка в округлении — выдаёт безалаберность в прикладной области. Это важно. Автору — радуйтесь поддержке, но обращайте особое внимание на критику, она делает Вас лучше.
Ты где здесь ошибку в округлении нашел?
Ну и запятые проверь у себя в сообщении.