В этой статье будет постепенно публиковаться набор кратких шпаргалок по использованию методов языка и спосбов разработки на платформе 1С:8.2 (часть из них применима и к 8.1, но об этом упоминаться не будет).
Вопрос Как сделать так, чтобы автоматически рассчитывалась сумма (Сумма = Количество*Цена) при изменении Цены или Количества в форме документа.
Ответ В свойствах элементов формы «Количество» и «Цена» прописывается вызов события «ПриИзменении».
В модуле формы, процедура «при изменении»:
&НаКлиенте Процедура МатериалыКоличествоПриИзменении(Элемент) СтрокаТабличнойЧасти = Элементы.Материалы.ТекущиеДанные; СтрокаТабличнойЧасти.Сумма = СтрокаТабличнойЧасти.Количество * СтрокаТабличнойЧасти.Цена; КонецПроцедуры
где Элементы.Материалы.ТекущиеДанные — обращение к коллекции элементов формы*, используя свойство «Элементы» объекта «УправляемаяФорма» (все свойства и методы объекта встроенного языка «УправляемаяФорма» доступны нам тут, т.к. мы находимся в Модуле Формы)
*Коллекция элементов формы является объектом встроенного языка «ВсеЭлементыФормы», содержащим все элементы формы. Т.е. это программный аналог корня дерева элементов формы. Каждый элемент формы можно получить через точку от объекта «ВсеЭлементыФормы», т.е. указав его имя в качестве свойства этого объекта. В данном случае идет обращение к табличной части «Материалы» документа (Элементы.Материалы). Табличная часть документа — это объект «ТаблицаФормы», у которого есть свойство «ТекущиеДанные». В результате выполнения команды «СтрокаТабличнойЧасти = Элементы.Материалы.ТекущиеДанные;» переменная СтрокаТабличнойЧасти будет содержать объект «ДанныеФормыСтруктура», в котором есть данные, находящиеся в текущей строке табличной части документа. Где текущая строка — это текущая интерактивно, т.е. та, на которой стоит курсор пользователя. В синакс-помощнике см. раздел «Интерфейс — ТаблицаФормы — Свойства».
Вопрос Что означает галочка «Клиент» в свойствах общих модулей.
Ответ Она означает, что экземпляры этого модуля будут скомпилированы в контексте тонкого клиента и в контексте веб-клиента.
Вопрос о динамическом создании форм и программном обращении к ним.
ОтветЕсли основная форма объекта не создана и не назначена в конфигураторе, то она будет создаваться автоматически при каждом обращении к ней — как интерактивном (вызов пользователем из меню списка документов, например), так и программном. Пример программного обращения к форме:
ФормаСписка = ПолучитьФорму("Справочник.Клиенты.ФормаСписка");
Основные формы можно подменять формами собственной разработки, созданными в кострукторе форм.
Вопрос о событиях форм.
Ответ Существует два вида событий форм:
- Назначаемые в формах (имя процедуры создается и назначается элементу формы, набор этих событий фиксирован для каждого элемента формы, но название может быть произвольным). Назначить событие можно не только стандартным путем в свойствах элемента формы, но и программно, с помощью метода УстановитьДействие()
- Фиксированные — с предопределенными назначением и названием
Вопрос о видах модулей.
Ответ Виды модулей:
Модуль управляемого приложения. Выполняется при старте 1С:Предприятия в режимах тонкого клиента и веб-клиента. Переменные и процедуры этого модуля будут доступны в любом другом модуле конфигурации, кроме модуля внешнего соединения. Этому модулю доступны экспортируемые переменные и процедуры общих модулей.
Общие модули. Сами по себе не выполняются. Служат для хранения и исполнения процедур, вызываемых во время исполнения других модулей. Общий модуль будет глобальным, если в свойствах этого модуля установить флаг «Глобальный«. В этом случае процедуры этого модуля компилируются не при обращении к ним, а при запуске системы и обращение к этим функциям осуществляется по их имени, без приставки через точку наименования самого общего модуля.
Модули Объектов. Вызывается при интерактивном создании объекта(документа, элемента справочника) пользователем либо при программном создании объекта средствами встроенного языка (СоздатьЭлемент(), СоздатьДокумент()), а также при различных действиях с этим объектом (справочником, документом), которые влекут за собой вызов предопределенных процедур, которые могут быть описаны в модуле объекта, например, «ПриЗаписи()».
Модули формы. Модуль формы исполняется при создании объекта УправляемаяФорма — программно (ПолучитьФорму(), ОткрытьФорму()) или интерактивно при открытии формы пользователем.
Модуль сеанса. Выполняется при старте 1С:Предприятия в момент загрузки конфигурации — для инициализации параметров сеанса и отработки действий. связанных с сеансом работы. Не содержит экспортируемых процедур, но может использовать процедуры из общих модулей.
Модуль внешнего соединения. Используется для размещения процедур, прорабатываемых в сессии внешнего соединения.
Модуль менеджеров. Для каждого прикладного объекта существует менеджер, предназначенный для управления этим объектом как объектом конфигурации. Менеджер помогает создавать объекты, работать с формами и макетами. Процедуры модуля менеджера позволяют расширять функциональность менеджеров, предоставляемых системой — так можно описать собственные методы для объекта, которые относятся не к конкретному экземпляру объекта базы данных, а к самому объекту конфигурации.
Модуль команды. Команды — объекты, подчиненные прикладным объектам и конфигурации в целом. У каждой команды есть модуль команды, в котором можно описать предопределенную процедуру ОбработкаКоманды() для выполнения этой команды.
Вопрос о контексте
Ответ Для доступа к свойствам и методам языка в каком-то контексте, нужно сначала понять их состав, названия, типы. Чтобы узнать, какие свойства контекста у модуля формы какого-либо объекта, удобно использовать свойство «ЭтаФорма». Рассчитывая в режиме отладки значение этого свойства, можно увидеть полный состав того, что доступно в этом контексте. Аналогично, свойства контекста модуля объекта или набора записей – при отладке в модуле объекта удобно использовать свойство «ЭтотОбъект».
Вопрос Как сделать так, чтобы при открытии формы списка справочника, подчиненного владельцу, ограничить состав отображаемых граф формы, но только в том случае, когда форма открывается с предустановленным отбором по конкретному владельцу.
Ответ Для этого нужно создать в конфигураторе форму списка этого справочника (т.е. отказаться от автоматической ее генерации), затем в свойствах формы задать вызов события «ПриСозданииНаСервере». Код процедуры с пояснениями в комментариях:
// наименование процедуры и директива "НаСервере" генерируются автоматически, при назначения события форме &НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) // Параметры - свойство управляемой формы, Отбор - элемент коллекции параметров формы, // Свойство(<Ключ>) - метод, определенный для структуры, позволяющий проверить, есть ли такое свойство у структуры. Если Параметры.Отбор.Свойство("Владелец") Тогда // само ограничение видимости колонок, например, колонки "Код" // Элементы - свойство управляемой формы, позволяющее получить доступ ко всем // элементам формы Элементы.Код.Видимость = Ложь; КонецЕсли; КонецПроцедуры
Вопрос о внутренней структуре таблиц, создаваемых 1С:Предприятием на этапе конфигурирования для хранения плана счетов
Ответ На основе объекта конфигурации «План счетов» платформа создает в базе данных таблицы, в которых будет храниться инфомация о том, какие счета (и каким образом) будет использовать предприятие. По любому счету или субсчету может вестись аналитический учет в разрезе субконто, описанных в плане видов характеристик. Для описания используемых субконто система создает в плане счетов специальную табличную часть ВидыСубконто, которая не видна в конфигураторе, но доступна средстами встроенного языка. При программировании движений в момент проведения документов в соответствующем регистре бухгалтерии нужно заполнить эти дополнительные поля, например, СчетДт и СчетКт, КоличествоДт и КоличествоКТ, СубконтоДт и СубконтоКт, примерно так: Движение.СчетКт = ПланыСчетов.Основной.РасчетыСПоставщиками; Движение.СубконтоДт[ПланыВидовХарактеристик.ВидыСубконто.Материалы] = ТекСтрокаМатериалы.Материал; т.к. платформа добавляет их к таблицам на основании плана счетов.
Вопрос Что означает флажок «Корреспонденция» в регистре бухгалтерии
Ответ Флажок «Корреспонденция» говорит о том, что создаваемый регистр бухгалтерии поддерживает корреспонденции, т.е. каждая запись регистра имеет дебетовую и кредитовую часть, что позволит получать информацию не только об остатках и оборотах по счетам, но и корреспонденциях между счетами.
Вопрос Что означает флажок «Предопределенное» в свойствах регламентного задания в конфигураторе
Ответ Флажок «Предопределенное» в свойствах регламентного задания (в конфигураторе) говорит о том, что после запуска в режиме 1С:Предприятие будет создано одно предопределенное регламентное задание. В противном случае такое задание пришлось бы создавать средствами встроенного языка.
Вопрос Что такое планировщик заданий, для чего он нужен.
Ответ Планировщик заданий — это клиентское соединение с информационной базой, служащее для автоматического запуска регламентных заданий в файловом вариане работы 1С;Предприятия. Для этого в конфигураторе 1С:Предприятия создается специальная обработка, которая запускается в отдельном соединении с информационной базой в режиме 1С:Предприятие и больше не закрываются — ни обработка, ни это соединение. Дело в том, что в клиент-серверном варианте работы информационной базы регламентные задания запускаются автоматически менеджером кластера серверов 1С:Предприятия, а в файловом варианте такого «промежуточного звена», которое могло бы взять на себя автоматическое выполнение заданий, не существует — есть только клиенты и информационная база. Поэтому для автоматического выполнения регламентных заданий в файломвом варианте работы необходимо всегда иметь одно работающее клиентское соединение с информационной базой, которое будет заниматься только запуском заданий по расписанию.
Вопрос Как при сохранении какого-либо значения программным путем обновить внешний вид 1С:Предприятия — командный интерфейс, рабчий стол, открытые формы (с учетом нового значения).
Ответ Обычно эта возможность требуется, когда сохраняемое значение должно повлиять на внешний вид 1С:Предприятия. Для реализации такой возможности, чтобы внешний вид изменился сразу, т.е. без перезахода пользователем, создается событие формы «После записи»:
&НаКлиенте Процедура ПослеЗаписи(ПараметрыЗаписи) ОбновитьИнтерфейс(); КонецПроцедуры
Вопрос Почему открытие некоторых окон блокирует другие окна.
Ответ Так происходит, когда в свойствах формы свойство «РежимОткрытияОкна» установлено в значение «Блокировать окно владельца». Если изменить на значение «Независимый», то окно будет открываться, не блокируя другие окна (см. раздел «Использование» в свойствах формы).
Вопрос Как программно изменить структуру дерева распределенной информационной базы.
Ответ Механизм распределенных информационных баз содержит программное средство конфигурирования структуры узлов распределенной базы. Для этого существует метод УстановитьГлавныйУзел() объекта ПланыОбменаМенеджер. В параметре этого метода передается ссылка на узел плана обмена распределенной информационной базы, который устанавливается главным для текущей базы. Также в этом параметре может быть передано значение Неопределено, тогда у текущей базы будет отсутствовать главный узел, т.е. она станет корневым узлом.
Пример:
// В информационной базе Узла2. ПланыОбменаМенеджер.УстановитьГлавныйУзел(Неопределено); // В информационной базе Узла1. ПланыОбменаМенеджер.УстановитьГлавныйУзел(Узел2);
При этом будут удалены все записи регистрации изменений конфигурации Узла2, относящиеся к Узлу2, передача изменений конфигурации будет возможна теперь только от Узла2 к Узлу1. Записи регистрации изменения данных удалены не будут, т.к. передача данных будет по-прежнему возможна между этими узлами.
Создание распределенной информационной базы из баз с одинаковой конфигурацией:
// В информационных базах Узла2, Узла3 и Узла4. ПланыОбменаМенеджер.УстановитьГлавныйУзел(Узел1);
Вопрос В каких случаях вызывается событие «ОбработкаВыбора» формы документа.
Ответ Это событие вызывается в двух случаях: когда в форме выполнен интрерактивный выбор и когда в форме вызван метод ОповеститьОВыборе().
Вопрос Можно ли из встроенного языка менять список выбора, который генеририруется платформой автоматически в автогенерируемых формах.
Ответ Да, можно. Для этого используется обработчик события Обработка получения данных выбора, модуль которого располагается в модуле менеджера объекта. Например, в модуле менеджера справочника, когда в поле ввода подбирается один из элементов этого справочника.
Вопрос Как назначить произвольную форму выбора ссылки на объект, являющийся типом реквизита другого объекта сразу для всех форм этого другого объекта. Предположим, эта произвольная форма уже сконструирована в метаданных, например, произвольная форма выбора сотрудника в справочнике сотрудников. В документе «Оказание услуг» есть реквизит «Мастер», со ссылкой на справочник сотрудников. Требуется, чтобы во всех формах документа «Оказание услуг» при открытии списка сотрудников для выбора, открывалась эта произвольная сконструированная форма.
Ответ Для этого нужно указать ссылку на эту форму в свойстве Форма выбора реквизита документа «Оказание услуг» (а не указывать в каждой форме для каждого поля «Мастер» отдельно). Путь: Конфигурация — Документы — двойной щелчок на документе «ОказаниеУслуг» — Данные — Реквизиты — двойной щелчок на реквизите Мастер — свойство «Форма выбора» в разделе «Представление» открывшихся свойств.
Вопрос Где размещать проверку заполнения реквизита объекта.
Ответ Чтобы проверка заполнения выполнялась во всех формах, где используется этот реквизит, реализовывается это следующим образом.
Интерактивная проверка. Путь: Конфигурация — Документы — двойной щелчок на документе «ОказаниеУслуг» — Данные — Реквизиты (или Табличные части — нужный реквизит) — двойной щелчок на реквизите — свойство «Проверка заполнения» в разделе «Представление» открывшихся свойств = «Выдавать ошибку».
Программная проверка. В модуле объекта нужно разместить обработчик с предопределенным именем ОбработкаПроверкиЗаполнения() (он по умолчанию запускается автоматически при записи формы) примерно такого вида:
Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты) // удаляем реквизит табличной части "НаборСвойств" из массива "ПроверяемыеРеквизиты" //(массив ПроверяемыеРеквизиты уже содержит реквизиты со значением "Выдавать ошибку" в свойстве Проверка заполнения) // это удаление нужно делать, если в конфигураторе у реквизита установлено "Выдавать ошибку", // а если оно не установлено, то потребовалось бы добавить реквизит в массив проверяемых реквизитов ПроверяемыеРеквизиты.Удалить(ПроверяемыеРеквизиты.Найти("ПереченьНоменклатуры.НаборСвойств")); // а если оно не установлено, то потребовалось бы добавить реквизит в массив проверяемых реквизитов: //ПроверяемыеРеквизиты.Добавить("ПереченьНоменклатуры.НаборСвойств"); Индекс = 0; Для Каждого ТекСтрокаПереченьНоменклатуры Из ПереченьНоменклатуры Цикл Индекс = Индекс + 1; // эту проверку лучше поместить в запрос, грамотнее будет, (но здесь мы упрощаем ее для краткости кода, а не для лучшей работы) Если ТекСтрокаПереченьНоменклатуры.Номенклатура.ВидНоменклатуры = Перечисления.ВидыНоменклатуры.Материал Тогда Если Не ЗначениеЗаполнено(ТекСтрокаПереченьНоменклатуры.НаборСвойств) Тогда Сообщение = Новый СообщениеПользователю(); Сообщение.Текст = "В строке " + Индекс + " списка Перечень номенклатуры не заполнена колонка Набор свойств"; Сообщение.Поле = "ПереченьНоменклатуры[" + Строка(Индекс - 1) + "].НаборСвойств"; Сообщение.УстановитьДанные(ЭтотОбъект); Сообщение.Сообщить(); // если хотим отказать пользователю в проведении или в перезаписи (когда документ уже проведен): Отказ = Истина; КонецЕсли; КонецЕсли; КонецЦикла; КонецПроцедуры
Вопрос О способах вызова экспортных процедур, описанных в модулях объектов.
Ответ Один из интересных способов — обращение к процедуре через точку после определения объекта. Пример. В модуле объекта справочника клиентов есть процедура «Проверка() Экспорт». Обратиться к ней можно, например, так: Справочники.Клиенты.НайтиПокоду(Код).ПолучитьОбъект().Проверка()
Вопрос Примеры программного кода обработки констант. Как изменить несколько констант подряд. Как вывести значения всех констант, существующих в конфигурации.
Ответ
// объект КонстантыМенеджер // СоздатьНабор() // Пример: установить новые значения нескольких констант. Набор = Константы.СоздатьНабор("Руководитель, Бухгалтер"); Набор.Рукводитель = "Каримова Наталья Андреевна"; Набор.Бухгалтер = "Кравцов Денис Федорович"; Набор.Записать();
При этом особенности внутренней реализации объекта КонстантыНабор таковы, что при записи набора констант будут вызваны для каждой константы, входящей в записываемый набор, обработчики событий: ОбработкаПроверкиЗаполнения(), ПередЗаписью() и ПриЗаписи() модуля менеджера значения константы (если они там определены).
===
// объект КонстантаМенеджер.<имя> // СоздатьМенеджерЗначения() // Пример: вывести значения всех констант, существующих в конфигурации. Для Каждого ОчереднаяКонст Из Константы Цикл ИмяКонст = ОчереднаяКонст.СоздатьМенеджерЗначения().Метаданные.Имя; ЗначениеКонст = ОчереднаяКонст.Получить(); Сообщить("Константа " + ИмяКонст + " = " + ЗначениеКонст); КонецЦикла;
===
// Получение значения константы Директор = Константы.Директор.Получить();
===
// Запись значения Константы.Директор.Установить("Иванов Петр Сидорович"); // или: Константы["Директор"]Установить("Иванов Петр Сидорович");
===
// Очистить значения всех констант Для Каждого ОчереднаяКонст Из Константы Цикл ОчереднаяКонст.Установить(Неопределено); КонецЦикла;
===
Вопрос Примеры программного кода работы со справочниками (аналогично с планами видов характеристик, с планами счетов, с планами видов расчета и с планами обмена).
Ответ
// ********************************* // Глобальный контекст // Справочники //Пример: вывести все типы ссылок на элементы справочников, существующие в конфигурации. Массив = Справочники.ТипВсеСсылки().Типы(); Для каждого ОчереднойТип Из Массив Цикл Сообщить(ОчереднойТип); КонецЦикла; // ********************************* // объект СправочникиМенеджер // .<имя справочника> // [<имя справочника>] // Для Каждого ... Из ... Цикл... КонецЦикла; // Пример: Создать новую группу справочника Номенклатура НоваяГруппа = Справочники.Номенклатура.СоздатьГруппу(); НоваяГруппа.Наименование = "Наша новая группа"; НоваяГруппа.Записать(); // Пример: получить ссылку на справочник Номенклатура Справочники["Номенклатура"].ПолучитьСсылку(); // ********************************* // объект СправочникМенеджер.<имя справочника> // НайтиПоКоду() // НайтиПоНаименованию() // НайтиПоРеквизиту() // ПустаяСсылка() // ПолучитьССылку() // .<имя предопределенного элемента справочника> // Пример: проверить, помечен ли на удаление элемент справочника Номенклатура с кодом 22. Если Справочники.Номенклатура.НайтиПоКоду(22).ПометкаУдаления Тогда Сообщить("Элемент с кодом 22 помечен на удаление"); КонецЕсли; // Пример: является ли группой элемент справочника Номенклатура с наименованием "Услуги" Если Справочники.Номенклатура.НайтиПоНаименованию("Услуги",Истина).ЭтоГруппа Тогда Сообщить("Элемент ""Услуги"" является группой"); КонецЕсли; // Пример: Проверить, что для всех элементов задан вид номенклатуры. ПустаяСсылкаПеречисления = Перечисления.ВидыНоменклатуры.ПустаяСсылка(); Если Не Справочники.Номенклатура.НайтиПоРеквизиту("ВидНоменклатуры", ПустаяСсылкаПеречисления).Пустая() Тогда Сообщить("Есть элементы, для которых не задан вид номенклатуры"); КонецЕсли; // Пример: передать пустую ссылку в параметр метода Выборка = Справочники.Номенклатура.Выбрать(Справочники.Номенклатура.ПустаяСсылка()); // ********************************* // объект СправочникМенеджер.<имя справочника> // Выбрать() // ВыбратьИерархически() // Пример: вывести список элементов, расположенных в корне справочника. Выборка = Справочники.Номенклатура.Выбрать(Справочники.Номенклатура.ПустаяСсылка()); Пока Выборка.Следующий() Цикл Если НЕ Выборка.ЭтоГруппа Тогда Сообщить(Выборка); КонецЕсли; КонецЦикла; // Пример: удалить все элементы иерархического справочника Выборка = Справочники.Номенклатура.ВыбратьИерархически(); Пока Выборка.Следующий() Цикл Выборка.Удалить(); КонецЦикла; // ********************************* // объект СправочникМенеджер.<имя справочника> // СоздаьтГруппу() // СоздатьЭлемент() //Пример: создать новый элемент справочника Сотрудники. НовыйЭлемент = Справочники.Сотрудники.СоздатьЭлемент(); НовыйЭлемент.Наименование = "Карбышев Николай Петрович"; // Заполнение табличной части ТрудоваяДеятельность: НовСтрТЧ = НовыйЭлемент.ТрудоваяДеятельность.Добавить(); НовСтрТЧ.Организация = "НИИ ЧАВО"; НовСтрТЧ.НачалоРаботы = Дата(2001,12,31); НовСтрТЧ.ОкончаниеРаботы = Дата(2006,12,31); НовСтрТЧ.Должность = "Маг певого ранга"; // запишем: НовыйЭлемент.Записать(); // ********************************* // объект СправочникОбъект.<имя справочника>, СправочникСсылка.<имя справочника> // Владелец // Родитель // Ссылка // Пример: запретить изменение подчиненных элементов, если у владельца установлено // соответствующее свойство ИзмененияЗапрещены в модуле формы элемента справочника Процедура ПередЗаписью(Отказ) Отказ = Владелец.ИзмененияЗапрещены; КонецПроцедуры // ********************************* // объект СправочникСсылка.<имя справочника> // ПолучитьОбъект() // СправочникОбъект.<имя справочника> // Скопировать() // Пример: изенить наименование элемента справочника Элемент = Справочники.Номенклатура.НайтиПоКоду(10).ПолучитьОбъект(); Элемент.Наименование = "Мое новое наименование"; Элемент.Записать(); //Пример: Заполнить справочник новыми данными Элемент = Справочники.Номенклатура.СоздатьЭлемент(); Элемент.Наименование = "Тестовый элемент"; Элемент.Записать(); Для ш=1 По 1000 Цикл НовыйЭлемент = Элемент.Скопировать(); НовыйЭлемент.Записать(); КонецЦикла; // ********************************* // объект СправочникВыборка.<имя справочника> // ссылка // Пример: заполнить табличную часть документа ПриходнаяНакладная всеми элементами из // указанной группы справочника Номенклатура Выборка = Справочники.Номенклатура.ВыбратьИерархически(ПолеВвода1); Пока Выборка.Следующий() Цикл СсылкаНаНоменклатуру = Выборка.Ссылка; Если СсылкаНаНоменклатуру.ЭтоГруппа Тогда Продолжить; КонецЕсли; Новаястрока = Материалы.Добавить(); НоваяСтрока.Материал = СсылкаНаНоменклатуру; КонецЦикла; // ********************************* // объект СправочникВыборка.<имя справочника> // ПолучитьОбъект() // Пример: пометить на удаление все элементы неиерархического справочника Выборка = Справочники.Клиенты.Выбрать(); Пока Выборка.Следующий() Цикл Выборка.ПолучитьОбъект().УстановитьПометкуУдаления(Истина); КонецЦикла; // ********************************* // Пример: программно создаем группу в справочнике и помещаем туда новый элемент //программно создаем новую группу справочника Номенклатура // Затем обойти все элементы справочника Номенклатура и элементы, не являющиеся группой поместить в новую папку НоваяГруппа = Справочники.Номенклатура.СоздатьГруппу(); НоваяГруппа.Наименование = "Тестовая группа справочника"; НоваяГруппа.Записать(); //программно создаем новый элемент справочника Номенклатура //и помещаем новый элемент в созданную ранее группу НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент(); НовыйЭлемент.Наименование = "Тестовый элемент справочника"; НовыйЭлемент.Родитель = НоваяГруппа.Ссылка; НовыйЭлемент.Записать(); //а теперь обходим все элементы справочника Номенклатура //и элементы, не являющиеся группой помещаем в новую папку Выборка = Справочники.Номенклатура.Выбрать(); Пока Выборка.Следующий() Цикл Если (НЕ Выборка.ЭтоГруппа) И (НЕ ЗначениеЗаполнено(Выборка.Родитель)) Тогда СпрОбъект = Выборка.ПолучитьОбъект(); СпрОбъект.Родитель = НоваяГруппа.Ссылка; СпрОбъект.Записать(); КонецЕсли; КонецЦикла;
Вопрос Последовательность событий при записи элемента справочника из формы элемента (записать и закрыть), а также при записи вида характеристики из формы элемента (записать и закрыть), при записи счета из формы счета (записать и закрыть), при записи вида расчета из формы вида расчета (записать и закрыть).
Ответ МОДУЛЬ ФОРМЫ КЛИЕНТ: «Перед записью» — МОДУЛЬ ФОРМЫ СЕРВЕР: «Обработка проверки заполнения на сервере» — МОДУЛЬ ОБЪЕКТА СЕРВЕР: «Обработка проверки заполнения» — МОДУЛЬ ФОРМЫ СЕРВЕР: «Перед записью на сервере» — (Начало транзакции записи — МОДУЛЬ ОБЪЕКТА СЕРВЕР: «Перед записью»- (запись)- «При записи»- МОДУЛЬ ФОРМЫ СЕРВЕР: «При записи на сервере» — Конец транзакции записи) — «После записи на сервере» — МОДУЛЬ ФОРМЫ КЛИЕНТ: «После записи» — «Перед закрытием» — «При закрытии».
Вопрос Последовательность событий при записи узла плана обмена из формы узла (записать и закрыть).
Ответ МОДУЛЬ ФОРМЫ КЛИЕНТ: «Перед записью» — МОДУЛЬ ФОРМЫ СЕРВЕР: «Обработка проверки заполнения на сервере» — МОДУЛЬ ОБЪЕКТА СЕРВЕР: «Обработка проверки заполнения» — МОДУЛЬ ФОРМЫ СЕРВЕР: «Перед записью на сервере» — (Начало транзакции записи — МОДУЛЬ ОБЪЕКТА СЕРВЕР: «Перед записью»- (запись узла плана обмена в базу данных)- «При записи»- МОДУЛЬ ФОРМЫ СЕРВЕР: «При записи на сервере» — Конец транзакции записи) — «После записи на сервере» — МОДУЛЬ ФОРМЫ КЛИЕНТ: «После записи» — «Перед закрытием» — «При закрытии».
Вопрос Примеры программного кода обработки документов.
Ответ
// ********************************* // Глобальный контекст // Документы //Пример: вывести все типы ссылок на Документы, существующие в конфигурации. Массив = Документы.ТипВсеСсылки().Типы(); Для каждого ОчереднойТип Из Массив Цикл Сообщить(ОчереднойТип); КонецЦикла; // ********************************* // объект ДокументыМенеджер // .<имя документа> // [<имя документа>] // Для Каждого ... Из ... Цикл... КонецЦикла; // Пример: получить макет для печати документа Оказание услуги Макет = Документы.ОказаниеУслуги.ПолучитьМакет("Печать"); // Пример: получить ссылку на каждый из документов, существующих в конфигурации Для каждого ОчереднойДок Из Документы Цикл Ссылка = ОчереднойДок.ПолучитьСсылку(); КонецЦикла; // ********************************* // объект ДокументМенеджер.<имя документа> // НайтиПоНомеру() // НайтиПоРеквизиту() // ПустаяСсылка() // Пример: проверить, проведен ли документ Приходная накладная с номером 13. Если Документы.ПриходнаяНакладная.НайтиПоНомеру(13).Проведен Тогда Сообщить("Документ с номером 13 проведен"); КонецЕсли; // Пример: Проверить, что во всех документах ПриходнаяНакладная заполнен реквизит Склад. ПустаяСсылкаСклада = Справочники.Склады.ПустаяСсылка(); Если Не Документы.ПриходнаяНакладная.НайтиПоРеквизиту("Склад", ПустаяСсылкаСклада).Пустая() Тогда Сообщить("Есть документы, у которых не заполнен реквизит ""Склад"""); КонецЕсли; // ********************************* // объект ДокументМенеджер.<имя документа> // Выбрать() // Пример: выбрать все документы ПриходнаяНакладная за текущий месяц. Выборка = Документы.ПриходнаяНакладная.Выбрать(НачалоМесяца(ТекущаяДата()),КонецМесяца(ТекущаяДата())); Пока Выборка.Следующий() Цикл Сообщить(Выборка); КонецЦикла; // ********************************* // объект ДокументМенеджер.<имя документа> // СоздатьДокумент() //Пример: создать новый документ ПриходнаяНакладная. НовыйДокумент = Документы.ПриходнаяНакладная.СоздатьДокумент(); НовыйДокумент.Дата = ТекущаяДата(); НовыйДокумент.Склад = Справочники.Склады.Основной; // Заполнение табличной части Материалы: НовСтрТЧ = НовыйДокумент.Материалы.Добавить(); НовСтрТЧ.Материал = Справочники.Номенклатура.НайтиПоКоду(2); НовСтрТЧ.Количество = 100; НовСтрТЧ.Цена = 2.5; НовСтрТЧ.Сумма = 20500; // запишем: НовыйДокумент.Записать(); // ********************************* // объект ДокументОбъект.<имя документа>, ДокументСсылка.<имя документа> // Ссылка // Пример: в модуле объекта вызвать процедуру проверки заполнения реквизитов документа Если НЕ ПроверитьЗаполнениеРеквизитов(ЭтотОбъект.Ссылка) Тогда Сообщить("Реквизиты документа не заполнены"); КонецЕсли; // ********************************* // объект ДокументСсылка.<имя документа> // ПолучитьОбъект() // объект ДокументОбъект.<имя документа> // Скопировать() // Пример: пометить документ на удаление НенужныйДокумент = Документы.ОказаниеУслуги.НайтиПоНомеру(10).ПолучитьОбъект(); НенужныйДокумент.УстановитьПометкуУдаления(Истина); // ********************************* // объект ДокументВыборка.<имя документа> // Ссылка // Пример: сформировать список ссылок на все документы ПриходнаяНакладная за текущий месяц. СписокНакладных = Новый СписокЗначений; Выборка = Документы.ПриходнаяНакладная.Выбрать(НачалоМесяца(ТекущаяДата()),КонецМесяца(ТекущаяДата())); Пока Выборка.Следующий() Цикл СписокНакладных.Добавить(Выборка.Ссылка); КонецЦикла; // ********************************* // объект ДокументВыборка.<имя документа> // ПолучитьОбъект() // Пример: удалить все документы ПриходнаяНакладная Выборка = Документы.ПриходнаяНакладная.Выбрать(); Пока Выборка.Следующий() Цикл Выборка.ПолучитьОбъект().Удалить(); КонецЦикла;
Вопрос Последовательность событий при записи документа из формы документа.
Ответ МОДУЛЬ ФОРМЫ КЛИЕНТ: «Перед записью» — МОДУЛЬ ФОРМЫ СЕРВЕР: «Обработка проверки заполнения на сервере» — МОДУЛЬ ОБЪЕКТА СЕРВЕР: «Обработка проверки заполнения» — МОДУЛЬ ФОРМЫ СЕРВЕР: «Перед записью на сервере» — (Начало транзакции записи — МОДУЛЬ ОБЪЕКТА СЕРВЕР: «Перед записью»- (запись)- «При записи»- МОДУЛЬ ФОРМЫ СЕРВЕР: «При записи на сервере» — Конец транзакции записи) — «После записи на сервере» — МОДУЛЬ ФОРМЫ КЛИЕНТ: «После записи».
Вопрос Последовательность событий при проведении документа из формы документа (провести и закрыть).
Ответ МОДУЛЬ ФОРМЫ КЛИЕНТ: «Перед записью» — МОДУЛЬ ФОРМЫ СЕРВЕР: «Обработка проверки заполнения на сервере» — МОДУЛЬ ОБЪЕКТА СЕРВЕР: «Обработка проверки заполнения» — МОДУЛЬ ФОРМЫ СЕРВЕР: «Перед записью на сервере» — (Начало транзакции записи — МОДУЛЬ ОБЪЕКТА СЕРВЕР: «Перед записью»- (запись)- «При записи» — «Обработка проведения»- МОДУЛЬ ФОРМЫ СЕРВЕР: «При записи на сервере» — Конец транзакции записи) — «После записи на сервере» — МОДУЛЬ ФОРМЫ КЛИЕНТ: «После записи» — «Перед закрытием» — «При закрытии».
Вопрос Последовательность событий при отмене проведения документа из формы документа (провести и закрыть).
Ответ МОДУЛЬ ФОРМЫ КЛИЕНТ: «Перед записью» — МОДУЛЬ ФОРМЫ СЕРВЕР: «Обработка проверки заполнения на сервере» — МОДУЛЬ ОБЪЕКТА СЕРВЕР: «Обработка проверки заполнения» — МОДУЛЬ ФОРМЫ СЕРВЕР: «Перед записью на сервере» — (Начало транзакции записи — МОДУЛЬ ОБЪЕКТА СЕРВЕР: «Перед записью»- «Обработка удаления проведения» — (запись)- «При записи»- МОДУЛЬ ФОРМЫ СЕРВЕР: «При записи на сервере» — Конец транзакции записи) — «После записи на сервере» — МОДУЛЬ ФОРМЫ КЛИЕНТ: «После записи».
Вопрос Примеры программного кода работы с перечислениями.
Ответ
// ********************************* // Глобальный контекст // Перечисления //Пример: получить значение перечисления по индексу. Перечисления.ВидыНоменклатуры.Получить(0); // ********************************* // объект ПеречисленияМенеджер // .<имя перечисления> // [<имя перечисления>] // Для Каждого ... Из ... Цикл... КонецЦикла; // Пример: получить количество значений перечисления Перечисления.["ВидыНоменклатуры"].Количество(); // ********************************* // объект ПеречислениеМенеджер.<имя> // .<имя значения перечисления> // [<имя значения перечисления>] // [<индекс элемента коллекции>] // Для Каждого ... Из ... Цикл... КонецЦикла; // ПустаяСсылка() // Пример: получить пустую ссылку на значение перечисления. ПустаяСсылкаПеречисления = Перечисления.ВидыНоменклатуры.ПустаяСсылка(); Если ТекущаяНоменклатура.ВидНоменклатуры = ПустаяСсылкаПеречисления Тогда // предложить заполнение вида номенклатуры КонецЕсли;
Вопрос Примеры программного кода работы с регистрами сведений.
Ответ
// ********************************* // Глобальный контекст // РегистрыСведений //Пример: получить текущую цену из периодического регитра сведений Цены. Элемент = Справочники.Номенклатура.НайтиПоКоду(4); Отбор = Новый Структура("Номенклатура",Элемент); ЗначенияРесурсов = РегистрыСведений.Цены.ПолучитьПоследнее(ТекущаяДата(),Отбор); Цена = ЗначенияРесурсов.Цена; // ********************************* // объект РегистрыСведенийМенеджер // .<имя регистра сведений> // [<имя регистра сведений>] // Для Каждого ... Из ... Цикл... КонецЦикла; // Пример: получить начальную цену из периодического регистра сведений Цены ИмяРегистра = "Цены"; Услуга = Справочники.Номенклатура.НайтиПоНаименованию("Диагностика"); Отбор = Новый Структура; Отбор.Вставить("Номенклатура",Услуга); Цена = РегистрыСведений[ИмяРегистра].ПолучитьПервое(ТекущаяДата(),Отбор).Цена; // ********************************* // объект РегистрСведенийМенеджер.<имя> // СоздатьКлючЗаписи() // Пример: активизировать требуемую строку списка регистра сведений. СтруктураКлючевыхПолей = Новый Структура; СтруктураКлючевыхПолей.Вставить("Период",Дата("20040331000000")); СтруктураКлючевыхПолей.Вставить("Номенклатура",Справочники.Номенклатура.НайтиПоКоду("0000006")); Элементы.Материалы.Текущаястрока = РегистрыСведений.Цены.СоздатьКлючЗаписи(СтруктураКлючевыхПолей); // ********************************* // объект РегистрСведенийМенеджер.<имя> // СоздатьНаборЗаписей() // [<индекс элемента коллекции>] // Для Каждого ... Из ... Цикл... КонецЦикла; // Пример: показать номенклатуру, цена на которую была установлена в заданные дату и время. Набор = РегистрыСведений.Цены.СоздатьНаборЗаписей(); Набор.Отбор.Период.Установить(ЗаданнаяДата,Истина); Набор.Прочитать(); Для каждого ОчереднаяЗапись Из Набор Цикл Сообщить("Номенклатура = "+ОчереднаяЗапись.Номенклатура+",цена="+ОчереднаяЗапись.Цена); КонецЦикла; // ********************************* // объект РегистрСведенийМенеджер.<имя> // СоздатьМенеджерЗаписи() //Пример: добавить новое значение цены в регистр Цены. Запись = РегистрыСведений.Цены.СоздатьМенеджерЗаписи(); Запись.Период = ТекущаяДата(); Запись.Номенклатура = Справочники.Номенклатура.НайтиПоКоду("0000005"); Запись.Цена = 554; Запись.Записать(); // ********************************* // объект РегистрСведенийМенеджер.<имя> // Выбрать() // ВыбратьПоРегистратору() // Пример: показать изменение цен на элемент номенклатуры в течение года. Отбор = Новый Структура("Номенклатура",Справочники.Номенклатура.НайтиПоКоду("0000006")); Выборка = РегистрыСведений.Цены.Выбрать(НачалоГода(ТекущаяДата()),Отбор); Пока Выборка.Следующий() Цикл Сообщить("Дата="+Выборка.Период+",цена="+Выборка.Цена); КонецЦикла;
Вопрос Последовательность событий при сохранении данных из формы записи регистра сведений (записать и закрыть).
Ответ МОДУЛЬ ФОРМЫ ЗАПИСИ КЛИЕНТ: «Перед записью» — МОДУЛЬ ФОРМЫ ЗАПИСИ СЕРВЕР: «Обработка проверки заполнения на сервере» — МОДУЛЬ НАБОРА ЗАПИСЕЙ СЕРВЕР: «Обработка проверки заполнения» — МОДУЛЬ ФОРМЫ ЗАПИСИ СЕРВЕР: «Перед записью на сервере» — (Начало транзакции записи — МОДУЛЬ НАБОРА ЗАПИСЕЙ СЕРВЕР: «Перед записью»- (запись набора записей в базу данных (количество=0)) — «При записи» — «ПередЗаписью» — (запись набора записей в базу данных (количество=1)) — «При записи» — МОДУЛЬ ФОРМЫ ЗАПИСИ СЕРВЕР: «При записи на сервере» — Конец транзакции записи) — «После записи на сервере» — МОДУЛЬ ФОРМЫ ЗАПИСИ КЛИЕНТ: «После записи» — «Перед закрытием» — «При закрытии».
Особенность внутренней реализации объекта РегистрСведенийМенеджерЗаписи.<имя> таковы, что в случае сохранения существующей записи регистра сведений обработчики события ПередЗаписью() и ПриЗаписи() модуля набора записей будут вызваны дважды: сначала для старого набора записей (с количеством записей 0) и затем для нового (с количеством записей 1).
Вопрос Последовательность событий при сохранении данных из формы набора записей регистра сведений (записать и закрыть), а также при сохранении набора записей регистра накопления из формы набора записей, при сохранении набора записей регистра бухгалтерии из формы и при сохранении набора записей регистра расчета из формы.
Ответ МОДУЛЬ ФОРМЫ НАБОРА ЗАПИСЕЙ КЛИЕНТ: «Перед записью» — МОДУЛЬ ФОРМЫ НАБОРА ЗАПИСЕЙ СЕРВЕР: «Обработка проверки заполнения на сервере» — МОДУЛЬ НАБОРА ЗАПИСЕЙ СЕРВЕР: «Обработка проверки заполнения» — МОДУЛЬ ФОРМЫ НАБОРА ЗАПИСЕЙ СЕРВЕР: «Перед записью на сервере» — (Начало транзакции записи — МОДУЛЬ НАБОРА ЗАПИСЕЙ СЕРВЕР: «Перед записью»- (запись набора записей в базу данных) — «При записи» — МОДУЛЬ ФОРМЫ НАБОРА ЗАПИСЕЙ СЕРВЕР: «При записи на сервере» — Конец транзакции записи) — «После записи на сервере» — МОДУЛЬ ФОРМЫ НАБОРА ЗАПИСЕЙ КЛИЕНТ: «После записи» — «Перед закрытием» — «При закрытии».
Вопрос Примеры программного кода работы с регистрами накопления, регистрами бухгалтерии и регистрами расчета.
Ответ
// ********************************* // Глобальный контекст // РегистрыНакопления //Пример: выполнить полный пересчет итогов регистраОстаткиМатериалов. РегистрыНакопления.ОстаткиМатериалов.ПересчитатьИтоги(); // ********************************* // объект РегистрыНакопленияМенеджер // .<имя регистра накопления> // [<имя регистра накопления>] // Для Каждого ... Из ... Цикл... КонецЦикла; // Пример: рассчитать итоги регистра ОстаткиМатериалов на указанную дату. ИмяРегистра = "ОстаткиМатериалов"; РегистрыНакопления[ИмяРегистра].УстановитьПериодРассчитанныхитогов(УказаннаяДата); // ********************************* // объект РегистрНакопленияМенеджер.<имя> // СоздатьКлючЗаписи() // Пример: активизировать требуемую строку списка регистра накопления. СтруктураКлючевыхПолей = Новый Структура; СтруктураКлючевыхПолей.Вставить("Регистратор",Документы.ПриходнаяНакладная.НайтиПоНомеру("0000002")); СтруктураКлючевыхПолей.Вставить("НомерСтроки",2); Элементы.Материалы.Текущаястрока = РегистрыНакопления.ОстаткиМатериалов.СоздатьКлючЗаписи(СтруктураКлючевыхПолей); // ********************************* // объект РегистрНакопленияМенеджер.<имя> // СоздатьНаборЗаписей() // [<индекс элемента коллекции>] // Для Каждого ... Из ... Цикл... КонецЦикла; // Пример: получить движения документа. НужныйДокумент = Документы.ПриходнаяНакладная.НайтиПоНомеру(4); Движения = РегистрыНакопления.ОстаткиМатериалов.СоздатьНаборЗаписей(); Движения.Отбор.Регистратор.Значение = НужныйДокумент; Движения.Прочитать(); Для каждого ОчередноеДвижение Из Движения Цикл // алгоритм обработки движений КонецЦикла; // ********************************* // объект РегистрНакопленияМенеджер.<имя> // Выбрать() // ВыбратьПоРегистратору() //Пример: выбрать все записи регистра ОстаткиМатериалов за текущий месяц. Выборка = РегистрыНакопления.ОстаткиМатериалов.Выбрать(НачалоМесяца(ТекущаяДата()),КонецМесяца(ТекущаяДата())); Пока Выборка.Следующий() Цикл Сообщить("Дата="+Выборка.Период+",цена="+Выборка.Цена); КонецЦикла;
Вопрос О проведении документов и видах блокировок в модуле проведения.
Ответ При проведении документов обычно нужно выполнить какие-то движения.
ВАРИАНТ 1. Если сначала выполняется запись движений, а потом их чтение (для контроля и отказа от проведения, если неудачно), то блокировка устанавливается командой типа:
Движения.ОстаткиНоменклатуры.БлокироватьДляИзменения = Истина;
ВАРИАНТ 2. Однако, бывают случаи, когда сначала нужно выполнить чтение, а уже потом запись.
В этом случае блокировка выполяняется методом «БлокировкаДанных», примерно так:
Блокировка = Новый БлокировкаДанных; ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиНоменклатуры"); ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный; ЭлементБлокировки.ИсточникДанных = СписокНоменклатуры; // СписокНоменклатуры - табличная часть документа ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура", "Номенклатура"); // сопоставляем реквизит табличной части измерению регистра накопления Блокировка.Заблокировать();
Снимется эта блокировка автоматически, в момент окончания проведения.
Общая схема проведения выглядит так:
//**********************************************************************************************
// сообщаем, какие движения записать в конце проведения
//**********************************************************************************************
// Установим необходимость блокировки данных в затрагиваемых регистрах
//**********************************************************************************************
// Запишем пустые наборы записей чтобы читать остатки без учета данных в документе
//**********************************************************************************************
// Выполнение запроса к базе данных для получения параметров новых движений
//**********************************************************************************************
// Движения
//**********************************************************************************************
// отказываемся от записи движений и проведения, если возникли ошибки
Пример модуля проведения по этой схеме:
Процедура ОбработкаПроведения(Отказ, Режим)
//**********************************************************************************************
// сообщаем, какие движения записать в конце проведения
Движения.ОстаткиМатериалов.Записывать = Истина;
Движения.СтоимостьМатериалов.Записывать = Истина;
Движения.Продажи.Записывать = Истина;
Движения.Управленческий.Записывать = Истина;
// Создать менеджер временных таблиц
МенеджерВТ = Новый МенеджерВременныхТаблиц;
Запрос = Новый Запрос;
// Укажем, какой менеджер временных таблиц использует этот запрос
Запрос.МенеджерВременныхТаблиц = МенеджерВТ;
Запрос.Текст =
«ВЫБРАТЬ
| ОказаниеУслугиПереченьНоменклатуры.Номенклатура,
| ОказаниеУслугиПереченьНоменклатуры.Номенклатура.ВидНоменклатуры КАК ВидНоменклатуры,
| СУММА(ОказаниеУслугиПереченьНоменклатуры.Количество) КАК КоличествоВДокументе,
| СУММА(ОказаниеУслугиПереченьНоменклатуры.Сумма) КАК СуммаВДокументе,
| ОказаниеУслугиПереченьНоменклатуры.НаборСвойств
|ПОМЕСТИТЬ НоменклатураДокумента
|ИЗ
| Документ.ОказаниеУслуги.ПереченьНоменклатуры КАК ОказаниеУслугиПереченьНоменклатуры
|ГДЕ
| ОказаниеУслугиПереченьНоменклатуры.Ссылка = &Ссылка
|
|СГРУППИРОВАТЬ ПО
| ОказаниеУслугиПереченьНоменклатуры.Номенклатура,
| ОказаниеУслугиПереченьНоменклатуры.Номенклатура.ВидНоменклатуры,
| ОказаниеУслугиПереченьНоменклатуры.НаборСвойств»;
Запрос.УстановитьПараметр(«Ссылка», Ссылка);
Результат = Запрос.Выполнить();
Запрос2 = Новый Запрос;
Запрос2.МенеджерВременныхТаблиц = МенеджерВТ;
Запрос2.Текст =
«ВЫБРАТЬ
| НоменклатураДокумента.Номенклатура,
| НоменклатураДокумента.ВидНоменклатуры,
| НоменклатураДокумента.КоличествоВдокументе,
| НоменклатураДокумента.СуммаВДокументе,
| ЕСТЬNULL(СтоимостьМатериаловОстатки.СтоимостьОстаток, 0) КАК Стоимость,
| ЕСТЬNULL(ОстаткиМатериаловОстатки.КоличествоОстаток, 0) КАК Количество,
| НоменклатураДокумента.НаборСвойств
|ИЗ
| НоменклатураДокумента КАК НоменклатураДокумента
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.СтоимостьМатериалов.Остатки(
| ,
| Материал В
| (ВЫБРАТЬ
| НоменклатураДокумента.Номенклатура
| ИЗ
| НоменклатураДокумента)) КАК СтоимостьМатериаловОстатки
| ПО НоменклатураДокумента.Номенклатура = СтоимостьМатериаловОстатки.Материал
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиМатериалов.Остатки(
| ,
| Материал В
| (ВЫБРАТЬ
| НоменклатураДокумента.Номенклатура
| ИЗ
| НоменклатураДокумента)) КАК ОстаткиМатериаловОстатки
| ПО НоменклатураДокумента.Номенклатура = ОстаткиМатериаловОстатки.Материал»;
//**********************************************************************************************
// Установим необходимость блокировки данных в регистрах СтоимостьМатериалов и ОстаткиМатериалов
Движения.СтоимостьМатериалов.БлокироватьДляИзменения = Истина;
Движения.ОстаткиМатериалов.БлокироватьДляИзменения = Истина;
//**********************************************************************************************
// Запишем пустые наборы записей чтобы читать остатки без учета данных в документе
Движения.СтоимостьМатериалов.Записать();
Движения.ОстаткиМатериалов.Записать();
//**********************************************************************************************
// Выполнение запроса к базе данных для получения параметров новых движений
Результат = Запрос2.Выполнить();
ВыборкаДетальныеЗаписи = Результат.Выбрать();
//**********************************************************************************************
// Движения
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
Если ВыборкаДетальныеЗаписи.Количество = 0 Тогда
СтоимостьМатериала = 0;
Иначе
СтоимостьМатериала = ВыборкаДетальныеЗаписи.Стоимость / ВыборкаДетальныеЗаписи.Количество;
КонецЕсли;
Если ВыборкаДетальныеЗаписи.ВидНоменклатуры = Перечисления.ВидыНоменклатуры.Материал Тогда
// регистр ОстаткиМатериалов Расход
Движение = Движения.ОстаткиМатериалов.Добавить();
Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
Движение.Период = Дата;
Движение.Материал = ВыборкаДетальныеЗаписи.Номенклатура;
Движение.НаборСвойств = ВыборкаДетальныеЗаписи.НаборСвойств;
Движение.Склад = Склад;
Движение.Количество = ВыборкаДетальныеЗаписи.КоличествоВДокументе;
// регистр СтоимостьМатериалов Расход
Движение = Движения.СтоимостьМатериалов.Добавить();
Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
Движение.Период = Дата;
Движение.Материал = ВыборкаДетальныеЗаписи.Номенклатура;
Движение.Стоимость = ВыборкаДетальныеЗаписи.КоличествоВДокументе*СтоимостьМатериала;
// Регистр Управленческий
// Первая проводка: Д 62(ДебиторскаяЗадолженность) – К 90 (Капитал) Розничная сумма
Движение = Движения.Управленческий.Добавить();
Движение.СчетДт = ПланыСчетов.Основной.ДебиторскаяЗадолженность;
Движение.СчетКт = ПланыСчетов.Основной.Капитал;
Движение.Период = Дата;
Движение.Сумма = ВыборкаДетальныеЗаписи.СуммаВДокументе;
Движение.СубконтоДт[ПланыВидовХарактеристик.ВидыСубконто.Клиенты] = Клиент;
// Вторая проводка: Д 90 (Капитал) – К 41 (Товары) – себестоимость
Движение = Движения.Управленческий.Добавить();
Движение.СчетДт = ПланыСчетов.Основной.Капитал;
Движение.СчетКт = ПланыСчетов.Основной.Товары;
Движение.Период = Дата;
Движение.Сумма = СтоимостьМатериала * ВыборкаДетальныеЗаписи.КоличествоВДокументе;
Движение.КоличествоКт = ВыборкаДетальныеЗаписи.КоличествоВДокументе;
Движение.СубконтоКт[ПланыВидовХарактеристик.ВидыСубконто.Материалы] = ВыборкаДетальныеЗаписи.Номенклатура;
КонецЕсли;
// Регистр Продажи
Движение = Движения.Продажи.Добавить();
Движение.Период = Дата;
Движение.Номенклатура = ВыборкаДетальныеЗаписи.Номенклатура;
Движение.Клиент = Клиент;
Движение.Мастер = Мастер;
Движение.Количество = ВыборкаДетальныеЗаписи.КоличествоВДокументе;
Движение.Выручка = ВыборкаДетальныеЗаписи.СуммаВДокументе;
Движение.Стоимость = СтоимостьМатериала * ВыборкаДетальныеЗаписи.КоличествоВДокументе;
КонецЦикла;
Движения.Записать();
//**********************************************************************************************
// отказываемся от записи движений и проведения, если возникли ошибки
Если Режим = РежимПроведенияДокумента.Оперативный Тогда
// Проверить отрицательные остатки
Запрос3 = Новый Запрос;
Запрос3.МенеджерВременныхТаблиц = МенеджерВТ;
Запрос3.Текст =
«ВЫБРАТЬ
| ОстаткиМатериаловОстатки.Материал,
| ОстаткиМатериаловОстатки.КоличествоОстаток
|ИЗ
| РегистрНакопления.ОстаткиМатериалов.Остатки(
| ,
| Материал В
| (ВЫБРАТЬ
| НоменклатураДокумента.Номенклатура
| ИЗ
| НоменклатураДокумента)
| И Склад = &Склад) КАК ОстаткиМатериаловОстатки
|ГДЕ
| ОстаткиМатериаловОстатки.КоличествоОстаток < 0"; Запрос3.УстановитьПараметр("Склад", Склад); Результат = Запрос3.Выполнить(); ВыборкаДетальныеЗаписи = Результат.Выбрать(); Пока ВыборкаДетальныеЗаписи.Следующий() Цикл Сообщение = Новый СообщениеПользователю(); Сообщение.Текст = "Не хватает " + Строка(- ВыборкаДетальныеЗаписи.КоличествоОстаток) + " единиц материала """ + ВыборкаДетальныеЗаписи.Материал + """"; Сообщение.Сообщить(); Отказ = Истина; КонецЦикла; КонецЕсли; КонецПроцедуры
Вопрос О получении данных из регистра остатков номенклатуры с помощью зароса и параметрах виртуальных таблиц.
Ответ При построении запроса к регистру накопления «ОстаткиНоменклатуры» в параметры виртуальной таблицы нужно передавать не дату документа, а гораздо более точный параметр, определяющий позицию докуента на оси времени — МоментВремени():
Запрос3 = Новый Запрос;
Запрос3.МенеджерВременныхТаблиц = МенеджерВТ;
Запрос3.Текст =
«ВЫБРАТЬ
| ОстаткиМатериаловОстатки.Материал,
| ОстаткиМатериаловОстатки.КоличествоОстаток
|ИЗ
| РегистрНакопления.ОстаткиМатериалов.Остатки(
| &Момент,
| Материал В
| (ВЫБРАТЬ
| НоменклатураДокумента.Номенклатура
| ИЗ
| НоменклатураДокумента)
| И Склад = &Склад) КАК ОстаткиМатериаловОстатки
|ГДЕ
| ОстаткиМатериаловОстатки.КоличествоОстаток < 0"; Запрос3.УстановитьПараметр("Момент", МоментВремени()); Запрос3.УстановитьПараметр("Склад", Склад);
Вопрос В табличной части документа есть реквизит сумма. Требуется вывести итог в шапку документа. Как это лучше сделать?
Ответ Подсчет итога по графе «Сумма» и заполнение реквизита шапки этим результатом лучше сделать в МодулеДокумента в процедуре-событии «Перед записью»:
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
СуммаПоДкументу = СписокНоменклатуры.Итог(«Сумма»); //, где
// СписокНоменклатуры — наименование табличной части,
// Сумма — название графы, по которой получаем итог
КонецПроцедуры
Вопрос Как в запросе осуществить выборку остатков и оборотов регистра накопления за заданный период, включая последнюю секунду, когда период задан параметрами виртуальной таблицы.
Ответ Особенность виртуальной таблицы регистра накопления такова, что когда конец выборки задается значением вида 12.13.2011 23:59:59 (т.е. конец дня), то последняя секунда дня не попадает в выборку. А если указать 12.13.2011 23:59:59 + 1 (т.е. добавить секунду), то в выборку попадут данные следующего дня, что тоже не правильно. Чтобы этого не происходило, дату окончания нужно задавать, используя метод «Граница». Пример:
Запрос = Новый Запрос;
Запрос.Текст =
«ВЫБРАТЬ
| ОстаткиМатериаловОстаткиИОбороты.Материал,
| ОстаткиМатериаловОстаткиИОбороты.НаборСвойств,
| ОстаткиМатериаловОстаткиИОбороты.Период
|ИЗ
| РегистрНакопления.ОстаткиМатериалов.ОстаткиИОбороты(
| &НачалоНедели,
| &КонецНедели,
| День,
| ДвиженияИГраницыПериода,
| Склад = &Склад) КАК ОстаткиМатериаловОстаткиИОбороты»;
Запрос.УстановитьПараметр(«Склад», Склад);
Запрос.УстановитьПараметр(«НачалоНедели», НачалоНедели(Дата));
Запрос.УстановитьПараметр(«КонецНедели», Новый Граница(КонецНедели(Дата),ВидГраницы.Включая));
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
// обработка результатов выборки
КонецЦикла;
Вопрос На какие данные можно опираться при проведении документов и на какие нельзя? В частности, в каком случае можно опираться на валюту, указанную в реквизите справочника договоров контрагента при проведении документа.
Ответ При проведении документа нужно следить за тем, чтобы выполняемые им движения были стабильно воспроизводимыми. Нельзя допускать ситуации, когда документ при проведении определяет, например, валюту как рубль, затем пользователь изменяет в договоре с контрагентом валюту на другую, и при повторном проведении документа валюта определяется в движениях уже как другая.
Документ в своих движениях может опираться на:
- свои реквизиты;
- значения данных, сконфигурированные таким образом, что они не могут быть потом независимо от этого документа изменены на другие;
- данные регистров, записи которых подчинены регистраторам.
Допустим, в документе есть реквизит «Договор». Для выполнения движений, предположим, требуется узнать валюту договора, т.е. валюта – это реквизит договора с контрагентом. И пусть договор – это элемент справочника «Договоры», подчиненного справочнику «Контрагенты». В таком случае при проведении документа мы можем использовать валюту из договора только в том случае, если конфигурированием мы добились того, что пользователь после записи в базу данных нового договора уже не может поменять в нем валюту. Такой запрет на изменение лучше всего разместить в предопределенной процедуре-событии модуля объекта справочника договоров «ПередЗаписью» (тогда при любом из возможных вариантов модификации этого справочника будет осуществляться соответствующая проверка):
Процедура ПередЗаписью(Отказ)
Если НЕ ЭтоНовый() Тогда
Если Валюта <> ЭтотОбъект.Ссылка.Валюта Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст =»Нельзя изменять валюту в уже записанном договоре»;
Сообщение.Поле = «Валюта»;
Сообщение.УстановитьДанные(ЭтотОбъект);
Сообщение.Сообщить();
Отказ = Истина;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Продолжение следует…
Спасибо, у Вас в строке ФораСписка = ПолучитьФорму(«Справочник.Клиенты.ФормаСписка»);
нужно
ФормаСписка = ПолучитьФорму(«Справочник.Клиенты.ФормаСписка»);
А как запросом извлечь инфу из регистра накоплений и вставить ее в колонки справочника?
Спасибо!
Большое спасибо
шпаргалкой вашей воспользовалась, спасибо!
Кратко и полезно.Еще структурировать и дополнить и вообще супер.
Если не сложно какую-нибудь информацию о том как перегнать ассеss базу в 1с 8,2
Подскажите пож. в какой последовательности внести закупочную цену (в евро) и как сформировать продажную цену,как внести % наценки?? Как вписать номер ГТД?
Как менять курс рубля к евро?
Спасибо
Спасибо
Помогите,пожалуйста.перехожу с 1с7 на 1C8.2 УПП .
1.При добавлении 4 субконто у счета,в форме списка появляется только пустая колонка -не видно ее содержание
2.В какой общий модуль нужно внести изменения,чтобы заполнить хотя-бы 3-е субконто у 62 счета при проведении Приходного Ордера (в модуле объекта в обрботкеПроведения не могу найти),может не там ищу?
Можно ли программно изменять(назначать) основную форму списка?
Как изминить параметр с 01.01.2013 23:59:59 на 01.01.2013 без указания времени?
НЕОБХОДИМОЙ ИНФОРМАЦИИ НЕ НАШЛА
СтрокаТабличнойЧасти = Элементы.Материалы.ТекущиеДанные;
СтрокаТабличнойЧасти.Сумма = СтрокаТабличнойЧасти.Количество * СтрокаТабличнойЧасти.Цена;
{Справочник.Магазины.Форма.ФормаЭлемента.Форма(3,25)}: Переменная не определена (Элементы)
СтрокаТабличнойЧасти = <>Элементы.Продукты.ТекущиеДанные; (Проверка: Толстый клиент (обычное приложение))
{Справочник.Магазины.Форма.ФормаЭлемента.Форма(8,25)}: Переменная не определена (Элементы)
СтрокаТабличнойЧасти = <>Элементы.Материалы.ТекущиеДанные; (Проверка: Толстый клиент (обычное приложение))
{Справочник.Магазины.Форма.ФормаЭлемента.Форма(3,25)}: Переменная не определена (Элементы)
СтрокаТабличнойЧасти = <>Элементы.Продукты.ТекущиеДанные; (Проверка: Толстый клиент (обычное приложение))
{Справочник.Магазины.Форма.ФормаЭлемента.Форма(8,25)}: Переменная не определена (Элементы)
СтрокаТабличнойЧасти = <>Элементы.Продукты.ТекущиеДанные; (Проверка: Толстый клиент (обычное приложение))
просто замечательно !
Отлично !!! Очень помогло !!!
Нашел что искал!!! В частности по заполнению табличной части документа программно !!!
как задать определенные значения для реквизита табличной части справочника. Хотелось бы видеть выпадающий список
Здравствуйте, как правильно написать обработку для просмотра справочников контрагентов и заполненных или не заполненных реквизитов документов?
Лучше всего на СКД