(за правильность не ручаюсь, буду благодарен за замечания)
- Включить возможность использования обычных форм (нужно для Консоли запросов):
- Сервис – Параметры – флаг «Управляемое приложение и обычное приложение»;
- свойства конфигурации – флаг «Использовать обычные формы в управляемом приложении»;
- Настройка конфигурации (свойства):
- свойства конфигурации – Режим управления блокировкой данных - Управляемый;
- добавить кнопку запуска отладки под Толстым клиентом (эта обработка Консоль запросов запускается только под ним).
- Создать Подсистемы (порядок – согласно порядку задачи: <конфигурация> – пкм – Открыть командный интерфейс):
- Оперативный учет;
- Бухгалтерский учет;
- Расчеты;
- Бизнес-процессы (или Управляемые формы) – по задаче;
- Сервис.
- Упорядочить подсистемы можно в режиме 1С Предприятие (Настройки – Настройка панели разделов).
- В созданные подсистемы (Подсистемы – пкм – Все подсистемы) добавить те объекты, которые должны в них входить (отображаться в интерфейсе):
- Создать Группы команд:
- Справочники;
- Документы;
- ПланыВидовХарактеристик;
- РегистрыСведений;
- РегистрыОУ;
- РегистрыБУ;
- РегистрыСПР.
- Например, подсистема "Оперативный учет" может включать:
- Справочник Номенклатура;
- Документ Приходная накладная;
- Документ Расходная накладная;
- Регистр накопления Остатки номенклатуры и т.д.
- Создать Группы команд:
- Распределить объекты подсистем по соответствующим группам команд.
- Настроить интерфейс клиентского приложения (<конфигурация> – пкм – Открыть интерфейс клиентского приложения):
- Сверху убрать Панель функций текущего раздела, добавить Панель открытых;
- Слева – Панель разделов.
- Включить возможность использования Консоли запросов (запускается только под Толстым клиентом):
- В модуле формы консоли изменить обработку исключения
Предупреждение(Сред(ОписаниеОшибки(),69));
наПоказатьПредупреждение(,Сред(ОписаниеОшибки(),69))
;
- В модуле формы консоли изменить обработку исключения
- Определяем список документов, используемых в решении. Все они явно описаны в задании, свои не добавлять.
- Рисуем ось времени. Отображаем на ней документы и оформляемые ими события хозяйственной жизни.
- Если в условии упоминаются услуги, то сразу готовим конфигурацию:
- проверяем (создаем)
Перечисления.ВидыНоменклатуры
со значениямиТовар
,Услуга
; - в справочник Номенклатура добавляем реквизит
ВидНоменклатуры
, типПеречислениеСсылка.ВидыНоменклатуры
;
- проверяем (создаем)
- Если в условии упоминается учетная политика (ФИФО, ЛИФО, средняя), то сразу готовим конфигурацию:
- проверяем (создаем)
Перечисления.УчетнаяПолитика
со значениямиФИФО
, ЛИФО, Средняя; - создать регистр сведений (периодический)
УчетнаяПолитика
(по нему будем определять метод учетной политики на дату документа):- периодичность - по заданию (например,
В пределах года
); - режим записи -
Независимый
; - добавить его в подсистему (например, ОУ);
- вкладка "Данные" - добавить ресурс
МетодСписанияСебестоимости
с типомПеречислениеСсылка.УчетнаяПолитика
.
- периодичность - по заданию (например,
- проверяем (создаем)
- Если ведется складской учет, то сразу готовим конфигурацию:
- добавляем справочник
Склады
; - в регистры накопления добавить измерение
Склад
, типСправочникСсылка.Склады
;
- добавляем справочник
- (При желании, сэкономит время на правильный ввод данных в документы) Настроить автоподсчет сумм (строка и документ) в Приходной и Расходной накладных (общий модуль + модули форм документов, в свойствах общего модуля проверить флаги «Клиент», «Сервер»):
- при изменении в строке табличной части
Количество
иЦена
; - при удалении или добавлении копированием.
- при изменении в строке табличной части
Это не обязательно. Процедуры можно создать для одного документа, а в модуль второго просто скопировать, назначив затем в свойствах.
Создать общий модуль РаботаСДокументами
:
-
- не забыть
Экспорт
; - установить флаг "Клиент (управляемое приложение)":
- не забыть
1 2 3 4 5 6 7 8 9 10 |
Процедура СуммаПоСтроке(ТекДанные) Экспорт ТекДанные.Сумма = ТекДанные.Количество * ТекДанные.Цена; КонецПроцедуры // для расчета цены при вводе значения в поле Сумма Процедура ЦенаПоСумме(ТекДанные) Экспорт Если ТекДанные.Количество <> 0 Тогда ТекДанные.Цена = ТекДанные.Сумма / ТекДанные.Количество; КонецЕсли; КонецПроцедуры |
Создать форму документа, в модуле формы определить процедуры:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
&НаКлиенте Процедура СписокНоменклатурыКоличествоПриИзменении(Элемент) ТекДанные = Элементы.СписокНоменклатуры.ТекущиеДанные; РаботаСДокументами.СуммаПоСтроке(ТекДанные); Объект.СуммаПоДокументу = Объект.СписокНоменклатуры.Итог("Сумма"); КонецПроцедуры &НаКлиенте Процедура СписокНоменклатурыЦенаПриИзменении(Элемент) ТекДанные = Элементы.СписокНоменклатуры.ТекущиеДанные; РаботаСДокументами.СуммаПоСтроке(ТекДанные); Объект.СуммаПоДокументу = Объект.СписокНоменклатуры.Итог("Сумма"); КонецПроцедуры &НаКлиенте Процедура СписокНоменклатурыСуммаПриИзменении(Элемент) ТекДанные = Элементы.СписокНоменклатуры.ТекущиеДанные; РаботаСДокументами.ЦенаПоСумме(ТекДанные); Объект.СуммаПоДокументу = Объект.СписокНоменклатуры.Итог("Сумма"); КонецПроцедуры // Для подсчета суммы по документу при копировании строки &НаКлиенте Процедура СписокНоменклатурыПриНачалеРедактирования(Элемент, НоваяСтрока, Копирование) Если Копирование Тогда Объект.СуммаПоДокументу = Объект.СписокНоменклатуры.Итог("Сумма"); КонецЕсли; КонецПроцедуры // Для подсчета суммы по документу при удалении строки &НаКлиенте Процедура СписокНоменклатурыПослеУдаления(Элемент) Объект.СуммаПоДокументу = Объект.СписокНоменклатуры.Итог("Сумма"); КонецПроцедуры |
- Определить количество ресурсов – по накапливаемым данным (количество, сумма, себестоимость, сумма продажи и т.д.). Добавить в соответствующий регистр, проверив соответствие типа, длины и точности.
- Определить количество измерений – по детализации ресурсов (склад, партия, контрагент, номенклатура и т.д.). Добавить соответствующие измерения.
- Проверить для измерений установку флага «Запрет незаполненных значений» (при необходимости).
- Регистр накопления:
- Прочее - флаг «Разрешить разделение итогов» - включить.
Замечание: Решение на двух регистрах более эффективно (работает быстрее, размеры таблиц меньше), но менее достоверно (необходима синхронизация регистров, на экзамене синхронизацию программно НЕ ДЕЛАТЬ!)
- Добавить реквизиты по заданию (например,
Склад
в шапке или полеПартия
вСписокНоменклатуры
). - Добавить и настроить форму:
- Форму документов создавать после добавления всех реквизитов документа (ускорение разработки).
- В командном интерфейсе форм в пункт «Перейти» добавить ссылки на регистры, установив соответствующие флажки.
- На вкладке «Движения»:
- Проведение – Разрешить (при ручном вводе движений – Запрещено);
- Оперативное проведение – Разрешить;
- Удаление движений – Удалять автоматически при отмене проведения.
- Сформировать движения (через конструктор, табличная часть выбирается только тогда, когда из неё заполняются измерения!) и определить методику контроля остатков:
- если для заполнения набора записей данные регистра не нужны – новая (если новая и приход – то контроль не нужен);
- если для заполнения набора записей данные регистра нужны - старая.
- В процедуре обработки проведения обработать дубли (например, простейший запрос с группировкой по Номенклатуре и суммированием Количества).
- Настроить автоподсчет сумм (строка и документ) в Приходной и Расходной накладных (общий модуль + модули форм документов, в свойствах общего модуля проверить флаги «Клиент», «Сервер»):
- При изменении в строке табличной части Количество и Цена;
- При удалении или добавлении копированием.
- Завести пользовательские данные в режиме 1С Предприятие, провести документ, проверить движения (добавить ссылку на соответствующий регистр в форму документа: (три верикальные точки) – Окно – Настройка панели навигации формы).
- Добавить в отчет необходимые таблицы (реальные и виртуальные).
- Если на рисунке отчета явно не указаны параметры (не установлены флаги и нет значений в полях), то считается, что это – пользовательские настройки (параметры виртуальной таблицы можно явно не задавать, определяются системой автоматически).
- Из таблиц выбрать необходимые поля, при этом опускаться до детализации и выбирать реквизиты, входящие в состав конкретного поля, не нужно (например, для конкретной задачи из поля Номенклатура регистра Остатки не нужно выбирать реквизит Разработчик, система сделает это автоматически, предоставив дополнительные возможности и упростив дальнейшую работу).
- Добавить нужные параметры (по заданию) или в конфигураторе, или в пользовательском режиме.
Пример решения задачи учета (в разрезе партий товаров)
Компания занимается оптовой торговлей. Поступление товаров отражается документом «Приходная накладная», продажа - «Расходная накладная». Помимо продажи товаров компания может оказывать дополнительные услуги, например, по доставке.
И услуги, и товары указываются в одной табличной части.
Складской учет товаров не ведется.
При проведении «Расходной накладной» при нехватке товара программа должна выдавать соответствующее предупреждение с указанием количества «нехватки» и не позволять проводить такой документ.
Списание себестоимости товаров должно быть организовано по партиям, в зависимости от текущего значения принятого на этот год в учетной политике компании метода списания себестоимости (FIFO или LIFO).
Обратите внимание - учетная политика действует год. На следующий год метод списания может измениться.
Необходимо построить отчеты по продажам товаров за период и остаткам товара на указанную дату.
Пункты по настройке интерфейса аналогичны вышеприведенным.
Видео по партионному учету (Леонтьев) https://www.youtube.com/watch?v=V0zYMdCBDZU
Видео по похожей задаче https://youtu.be/KoYAofD5qws
Общий алгоритм:
- Определить количество ресурсов – по накапливаемым данным (количество, сумма, себестоимость, сумма продажи и т.д.). Добавить в соответствующий регистр, проверив соответствие типа, длины и точности.
- Определить количество измерений – по детализации ресурсов (склад, партия, контрагент, номенклатура и т.д.). Добавить соответствующие измерения.
- Проверить установку флага «Запрет незаполненных значений» (при необходимости).
- Регистр накопления:
- Прочее - флаг «Разрешить разделение итогов» - включить.
Проанализируем условие задачи и таблицы из условия:
Необходимо построить отчеты по продажам товаров за период и остаткам товара на указанную дату.
Т.о. нам понадобятся 2 регистра накопления:
- первый - оборотный, по продажам;
- второй - остатков.
В регистрах будут храниться:
- Регистр
ОстаткиНоменклатуры:
измерения:
Номенклатура
, типСправочникСсылка.Номенклатура
;Партия
, типДокументСсылка.ПриходнаяНакладная
;
- ресурсы:
Количество
;Себестоимость
, типЧисло
(длина 12, точность 2);
- Регистр Продажи (вид регистра
Обороты
) (видео от Леонтьева, с 30 мин):- измерение:
Номенклатура
, типСправочникСсылка.Номенклатура
;
- ресурсы:
Количество
;Себестоимость
(дублирование, НО упростит формирование отчета);СуммаПродажи
, типЧисло
(длина 12, точность 2);
- измерение:
Замечание: Решение на двух регистрах более эффективно (работает быстрее, размеры таблиц меньше), но менее достоверно (необходима синхронизация регистров, на экзамене синхронизацию программно НЕ ДЕЛАТЬ!)
- Добавить реквизиты по заданию (например,
Склад
в шапке или полеПартия
вСписокНоменклатуры
). - Добавить и настроить форму:
- форму документов создавать после добавления всех реквизитов документа (ускорение разработки).
- в командном интерфейсе форм в пункт «Перейти» добавить ссылки на регистры, установив соответствующие флажки.
- На вкладке «Движения»:
- Проведение – Разрешить (при ручном вводе движений – Запрещено);
- Оперативное проведение – Разрешить;
- Удаление движений – Удалять автоматически при отмене проведения.
- Движения формировать через конструктор (табличная часть выбирается только тогда, когда из неё заполняются измерения!) и определить методику проведения:
- если для заполнения набора записей данные регистра не нужны – новая (если новая и приход – то контроль не нужен);
- если для заполнения набора записей данные регистра нужны - старая.
Особенности:
- Приходная накладная записывает движения только в регистр накопления
ОстаткиНоменклатуры
. - В запросе:
- условие - по ссылке на документ;
- группировка по
Номенклатура
, - суммируем
Количество
иСебестоимость
.
Порядок действий:
- Отметить
ПриходнаяНакладная
как регистратор для регистровОстаткиНоменклатуры
; - Сформировать движения (через конструктор), вручную заполнив в колонке "Выражение" поля
Партия
иСебестоимость
; - Сформировать запрос для выборки данных из документа для движений, указав:
- условия: ссылка на документ, вид номенклатуры - Товар;
- в качестве
Партия
-Ссылка
; - в качестве
Себестоимость
-Выборка.Сумма
(код процедуры ОбработкаПроведения см. ниже).
- Завести пользовательские данные в режиме 1С Предприятие, провести документ, проверить движения (добавить ссылку на соответствующий регистр в форму документа: (три верикальные точки) – Окно – Настройка панели навигации формы).
Код процедуры ОбработкаПроведения:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
Процедура ОбработкаПроведения(Отказ, Режим) Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ПриходнаяНакладнаяСписокНоменклатуры.Номенклатура КАК Номенклатура, | СУММА(ПриходнаяНакладнаяСписокНоменклатуры.Количество) КАК Количество, | СУММА(ПриходнаяНакладнаяСписокНоменклатуры.Сумма) КАК Сумма |ИЗ | Документ.ПриходнаяНакладная.СписокНоменклатуры КАК ПриходнаяНакладнаяСписокНоменклатуры |ГДЕ | ПриходнаяНакладнаяСписокНоменклатуры.Ссылка = &Ссылка | И ПриходнаяНакладнаяСписокНоменклатуры.Номенклатура.ВидНоменклатуры = &ВидНоменклатуры | |СГРУППИРОВАТЬ ПО | ПриходнаяНакладнаяСписокНоменклатуры.Номенклатура"; Запрос.УстановитьПараметр("Ссылка", Ссылка); Запрос.УстановитьПараметр("ВидНоменклатуры", Перечисления.ВидыНоменклатуры.Товар); РезультатЗапроса = Запрос.Выполнить(); Выборка = РезультатЗапроса.Выбрать(); // регистр ОстаткиНоменклатуры Приход Пока Выборка.Следующий() Цикл Движение = Движения.ОстаткиНоменклатуры.Добавить(); Движение.ВидДвижения = ВидДвиженияНакопления.Приход; Движение.Период = Дата; Движение.Номенклатура = Выборка.Номенклатура; Движение.Партия = Ссылка; Движение.Количество = Выборка.Количество; Движение.Себестоимость = Выборка.Сумма; КонецЦикла; Движения.ОстаткиНоменклатуры.Записывать = ИСТИНА; КонецПроцедуры |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
Процедура ОбработкаПроведения(Отказ, Режим) // определяем метод списания себестоимости МетодСписанияСебестоимости = РегистрыСведений.УчетнаяПолитика.ПолучитьПоследнее(Дата).МетодСписанияСебестоимости; Если НЕ ЗначениеЗаполнено(МетодСписанияСебестоимости) Тогда Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "Не установлен метод списания себестоимости"; Сообщение.Сообщить(); Отказ = Истина; Возврат; КонецЕсли; // очищаем движения регистров Движения.ОстаткиНоменклатуры.Записывать = ИСТИНА; Движения.Записать(); Движения.ОстаткиНоменклатуры.Записывать = ИСТИНА; // устанавливаем блокировку Блокировка = Новый БлокировкаДанных; ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиНоменклатуры"); ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный; // указываем источник данных (табличная часть в примере) ЭлементБлокировки.ИсточникДанных = СписокНоменклатуры; // указываем измерение и соответствующую колонку таблицы ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура", "Номенклатура"); Блокировка.Заблокировать(); // получаем данные для проведения Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | РасходнаяНакладнаяСписокНоменклатуры.Номенклатура КАК Номенклатура, | СУММА(РасходнаяНакладнаяСписокНоменклатуры.Количество) КАК Количество, | РасходнаяНакладнаяСписокНоменклатуры.Номенклатура.Представление КАК НоменклатураПредставление, | СУММА(РасходнаяНакладнаяСписокНоменклатуры.Сумма) КАК Сумма |ПОМЕСТИТЬ ВТТЧ_Товары |ИЗ | Документ.РасходнаяНакладная.СписокНоменклатуры КАК РасходнаяНакладнаяСписокНоменклатуры |ГДЕ | РасходнаяНакладнаяСписокНоменклатуры.Ссылка = &Ссылка | |СГРУППИРОВАТЬ ПО | РасходнаяНакладнаяСписокНоменклатуры.Номенклатура, | РасходнаяНакладнаяСписокНоменклатуры.Номенклатура.Представление | |ИНДЕКСИРОВАТЬ ПО | Номенклатура |; | |//////////////////////////////////////////////////////////////////////////////// |ВЫБРАТЬ | ВТТЧ_Товары.Номенклатура КАК Номенклатура, | ВТТЧ_Товары.Количество КАК Количество, | ВТТЧ_Товары.Номенклатура.Представление КАК НоменклатураПредставление, | ОстаткиНоменклатурыОстатки.Партия КАК Партия, | ОстаткиНоменклатурыОстатки.Партия.Представление КАК ПартияПредставление, | ЕСТЬNULL(ОстаткиНоменклатурыОстатки.КоличествоОстаток, 0) КАК КоличествоОстаток, | ЕСТЬNULL(ОстаткиНоменклатурыОстатки.СебестоимостьОстаток, 0) КАК СебестоимостьОстаток, | ВТТЧ_Товары.Номенклатура.ВидНоменклатуры КАК ЭтоУслуга, | ВТТЧ_Товары.Сумма КАК Сумма |ИЗ | ВТТЧ_Товары КАК ВТТЧ_Товары | ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиНоменклатуры.Остатки( | &МоментВремени, | Номенклатура В | (ВЫБРАТЬ | ВТТЧ_Товары.Номенклатура КАК Номенклатура | ИЗ | ВТТЧ_Товары КАК ВТТЧ_Товары)) КАК ОстаткиНоменклатурыОстатки | ПО ВТТЧ_Товары.Номенклатура = ОстаткиНоменклатурыОстатки.Номенклатура | |УПОРЯДОЧИТЬ ПО | ОстаткиНоменклатурыОстатки.Партия.МоментВремени |ИТОГИ | МАКСИМУМ(Количество), | СУММА(КоличествоОстаток), | МАКСИМУМ(Сумма) |ПО | Номенклатура"; Запрос.УстановитьПараметр("МоментВремени", МоментВремени()); Запрос.УстановитьПараметр("Ссылка", Ссылка); // откорректируем текст запроса по учетной политике (ФИФО или ЛИФО) Если МетодСписанияСебестоимости = Перечисления.УчетнаяПолитика.ЛИФО Тогда Запрос.Текст = СтрЗаменить(Запрос.Текст,"ОстаткиНоменклатурыОстатки.Партия.МоментВремени","ОстаткиНоменклатурыОстатки.Партия.МоментВремени УБЫВ"); КонецЕсли; РезультатЗапроса = Запрос.Выполнить(); ВыборкаНоменклатура = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам); Пока ВыборкаНоменклатура.Следующий() Цикл // для суммирования списанной себестоимости по номенклатуре для заполнения Стоимости регистра Продажи СписаннаяСебестоимость = 0; // если услуга, то записываем только регистр Продажи Если НЕ ВыборкаНоменклатура.ЭтоУслуга = Перечисления.ВидыНоменклатуры.Услуга Тогда // контроль остатков по сгруппированным в ИТОГАХ номенклатурным позициям Если ВыборкаНоменклатура.Количество > ВыборкаНоменклатура.КоличествоОстаток Тогда Сообщение = Новый СообщениеПользователю; Сообщение.Текст = СтрШаблон("По номенклатуре %1 не хватает %2 шт.", ВыборкаНоменклатура.НоменклатураПредставление, ВыборкаНоменклатура.Количество - ВыборкаНоменклатура.КоличествоОстаток); Сообщение.Сообщить(); Отказ = ИСТИНА; КонецЕсли; Если Отказ Тогда Продолжить; КонецЕсли; // списываем номенклатуру по партиям КоличествоВсегоСписать = ВыборкаНоменклатура.Количество; Выборка = ВыборкаНоменклатура.Выбрать(); // обходим детальные записи в группах ВыборкаНоменклатура Пока Выборка.Следующий() И КоличествоВсегоСписать > 0 Цикл // списываем минимальное из... Выборка.КоличествоОстаток - для учета партии КоличествоСписать = МИН(КоличествоВсегоСписать,Выборка.КоличествоОстаток); // решаем "проблему копеек" Если КоличествоВсегоСписать = Выборка.КоличествоОстаток Тогда СебестоимостьСписать = Выборка.СебестоимостьОстаток; Иначе СебестоимостьСписать = КоличествоСписать/Выборка.КоличествоОстаток*Выборка.СебестоимостьОстаток; КонецЕсли; // движения по регистру ОстаткиНоменклатуры Движение = Движения.ОстаткиНоменклатуры.Добавить(); Движение.ВидДвижения = ВидДвиженияНакопления.Расход; Движение.Период = Дата; Движение.Номенклатура = Выборка.Номенклатура; Движение.Партия = Выборка.Партия; Движение.Количество = КоличествоСписать; Движение.Себестоимость = СебестоимостьСписать; КоличествоВсегоСписать = КоличествоВсегоСписать - КоличествоСписать; // для регистра Продажи СписаннаяСебестоимость = СписаннаяСебестоимость + СебестоимостьСписать; КонецЦикла; Иначе // если услуга, то Себестоимость равна 0 СебестоимостьСписать = 0; КонецЕсли; // регистр Продажи Движение = Движения.Продажи.Добавить(); Движение.Период = Дата; Движение.Номенклатура = ВыборкаНоменклатура.Номенклатура; Движение.Количество = ВыборкаНоменклатура.Количество; Движение.Себестоимость = СписаннаяСебестоимость; Движение.СуммаПродажи = ВыборкаНоменклатура.Сумма; КонецЦикла; Движения.ОстаткиНоменклатуры.Записывать = Истина; Движения.Продажи.Записывать = Истина; КонецПроцедуры |
Особенности:
- При обработке проведения не забывать о проверке на "товар - услуга" (услуги в регистр накопления
ОстаткиНоменклатуры
не пишутся, и т.д.). - Сформировать движения (через конструктор, табличная часть выбирается только тогда, когда из неё заполняются измерения!) и определить методику контроля остатков:
-
- если для заполнения набора записей данные регистра не нужны – новая (если новая и приход – то контроль не нужен);
- если для заполнения набора записей данные регистра нужны - старая (если используются два регистра, то возможен вариант использования разных методик).
-
Порядок действий:
- Определить текущий метод списания себестоимости.
Код123456789101112МетодСписания = РегистрыСведений.УчетнаяПолитика.ПолучитьПоследнее(Дата).МетодСписанияСебестоимости;Если НЕ ЗначениеЗаполнено(МетодСписания) ТогдаСообщение = Новый СообщениеПользователю;Сообщение.Текст = "Не задан метод списания учетной политики";Сообщение.Сообщить();// отказ в проведенииОтказ = Истина;Возврат;КонецЕсли;[свернуть]
- Очистить движения регистров.
Код1234// очищаем движения регистровДвижения.ОстаткиНоменклатуры.Записывать = ИСТИНА;Движения.Записать();Движения.ОстаткиНоменклатуры.Записывать = ИСТИНА;[свернуть]
- Устанавливаем на регистры блокировку:
- копируем из Синтакс-помощника;
- пока закомментируем (т.к. данных пока нет, определим позже, по данным запроса);
Код123456789// устанавливаем блокировку//Блокировка = Новый БлокировкаДанных;//ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиНоменклатуры");//ЭлементБлокировки.УстановитьЗначение("Номенклатура", Справочники.Номенклатура);//ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;//ЭлементБлокировки.ИсточникДанных = ДокументОбъект.ВозвратнаяТара;//ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура", "Номенклатура");//ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Склад", "Склад");//Блокировка.Заблокировать();[свернуть]
- Получить из регистра данные для проведения:
- запросом с обработкой результатов получаем данные для проведения из табличной части и регистра накопления
ОстаткиНоменклатуры.Остатки
(с отбором ВидНоменклатуры <> Услуга):- выбираем
Номенклатура
,Количество
,Номенклатура.Представление
,Сумма
; - группируем по
Номенклатура
(убираем возможные дубли); - суммируем по
Количество
(определяем общее количество списываемой номенклатуры для контроля остатков),Сумма
(определяем сумму продажи); - ставим условия:
Ссылка
на эту РасходнуюНакладную;- условие на
ВидНоменклатуры
при отборе ставить не будем, т.к. в регистр Продажи должны писаться не только Товары, но и Услуги;
- помещаем во временную таблицу;
- индексируем по
Номенклатура
(будем далее соединять по этому полю); - добавляем второй запрос пакета запросов для получения данных из регистра накопления
ОстаткиНоменклатуры.Остатки;
- добавляем временную таблицу, выбираем
Номенклатура
,Номенклатура.Представление
(представления нужны для вывода сообщений),Количество,
Сумма
,ВидНоменклатуры
; - добавляем регистр накопления, устанавливаем параметры виртуальной таблицы;
Рисунки[свернуть]
- выбираем из регистра
КоличествоОстаток
,СебестоимостьОстаток
(для контроля остатков), обернуть вЕСТЬNULL()
(т.к. левое соединение будет); - связь таблиц по номенклатуре, ЛЕВОЕ соединение;
- на вкладке "Порядок" добавить поле
Партия.МоментВремени
,Сортировка - Возрастание
(для ФИФО); - на вкладке "Итоги" построим иерархию для партий товаров:
- "Группировочное поле" -
Номенклатура
; - "Итоговое поле" -
СУММА(КоличествоОстаток)
из регистра,МАКСИМУМ(Количество)
из документа - именно их мы будем сравнивать при контроле остатков,МАКСИМУМ(Сумма)
- сумма продажи;
- "Группировочное поле" -
- закрываем конструктор запросов.
- выбираем
- устанавливаем параметры запроса:
МоментВремени
какМоментВремени();
Ссылка
какСсылка();
-
откорректируем текст запроса по учетной политике (ФИФО или ЛИФО);Код1234// откорректируем текст запроса по учетной политике (ФИФО или ЛИФО)Если МетодСписанияСебестоимости = Перечисления.УчетнаяПолитика.ЛИФО ТогдаЗапрос.Текст = СтрЗаменить(Запрос.Текст,"ОстаткиНоменклатурыОстатки.Партия.МоментВремени","ОстаткиНоменклатурыОстатки.Партия.МоментВремени УБЫВ");КонецЕсли;[свернуть]Код запроса12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061// получаем данные для проведенияЗапрос = Новый Запрос;Запрос.Текст ="ВЫБРАТЬ| РасходнаяНакладнаяСписокНоменклатуры.Номенклатура КАК Номенклатура,| СУММА(РасходнаяНакладнаяСписокНоменклатуры.Количество) КАК Количество,| РасходнаяНакладнаяСписокНоменклатуры.Номенклатура.Представление КАК НоменклатураПредставление,| СУММА(РасходнаяНакладнаяСписокНоменклатуры.Сумма) КАК Сумма|ПОМЕСТИТЬ ВТТЧ_Товары|ИЗ| Документ.РасходнаяНакладная.СписокНоменклатуры КАК РасходнаяНакладнаяСписокНоменклатуры|ГДЕ| РасходнаяНакладнаяСписокНоменклатуры.Ссылка = &Ссылка||СГРУППИРОВАТЬ ПО| РасходнаяНакладнаяСписокНоменклатуры.Номенклатура,| РасходнаяНакладнаяСписокНоменклатуры.Номенклатура.Представление||ИНДЕКСИРОВАТЬ ПО| Номенклатура|;||////////////////////////////////////////////////////////////////////////////////|ВЫБРАТЬ| ВТТЧ_Товары.Номенклатура КАК Номенклатура,| ВТТЧ_Товары.Количество КАК Количество,| ВТТЧ_Товары.Номенклатура.Представление КАК НоменклатураПредставление,| ОстаткиНоменклатурыОстатки.Партия КАК Партия,| ОстаткиНоменклатурыОстатки.Партия.Представление КАК ПартияПредставление,| ЕСТЬNULL(ОстаткиНоменклатурыОстатки.КоличествоОстаток, 0) КАК КоличествоОстаток,| ЕСТЬNULL(ОстаткиНоменклатурыОстатки.СебестоимостьОстаток, 0) КАК СебестоимостьОстаток,| ВТТЧ_Товары.Номенклатура.ВидНоменклатуры КАК ЭтоУслуга,| ВТТЧ_Товары.Сумма КАК Сумма|ИЗ| ВТТЧ_Товары КАК ВТТЧ_Товары| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиНоменклатуры.Остатки(| &МоментВремени,| Номенклатура В| (ВЫБРАТЬ| ВТТЧ_Товары.Номенклатура КАК Номенклатура| ИЗ| ВТТЧ_Товары КАК ВТТЧ_Товары)) КАК ОстаткиНоменклатурыОстатки| ПО ВТТЧ_Товары.Номенклатура = ОстаткиНоменклатурыОстатки.Номенклатура||УПОРЯДОЧИТЬ ПО| ОстаткиНоменклатурыОстатки.Партия.МоментВремени|ИТОГИ| МАКСИМУМ(Количество),| СУММА(КоличествоОстаток),| МАКСИМУМ(Сумма)|ПО| Номенклатура";Запрос.УстановитьПараметр("МоментВремени", МоментВремени());Запрос.УстановитьПараметр("Ссылка", Ссылка);// откорректируем текст запроса по учетной политике (ФИФО или ЛИФО)Если МетодСписанияСебестоимости = Перечисления.УчетнаяПолитика.ЛИФО ТогдаЗапрос.Текст = СтрЗаменить(Запрос.Текст,"ОстаткиНоменклатурыОстатки.Партия.МоментВремени","ОстаткиНоменклатурыОстатки.Партия.МоментВремени УБЫВ");КонецЕсли;[свернуть]
- выполняем запрос и обходим группы номенклатуры;
Код123456789101112131415161718192021222324РезультатЗапроса = Запрос.Выполнить();ВыборкаНоменклатура = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);Пока ВыборкаНоменклатура.Следующий() Цикл// для суммирования списанной себестоимости по номенклатуре для заполнения Стоимости регистра ПродажиСписаннаяСебестоимость = 0;// если услуга, то записываем только регистр ПродажиЕсли НЕ ВыборкаНоменклатура.ЭтоУслуга = Перечисления.ВидыНоменклатуры.Услуга Тогда// здесь будет код обхода ВыборкаНоменклатура (контроль остатков по общему количеству к списанию)// здесь будет код обхода детальных записей (из ВыборкаНоменклатура)Иначе// если услуга, то Себестоимость равна 0СебестоимостьСписать = 0;КонецЕсли;// здесь будет запись движений регистра ПродажиКонецЦикла;[свернуть]
- выполняем контроль остатков по сгруппированным в ИТОГАХ номенклатурным позициям (детальные записи при нехватке обходить смысла нет);
Код12345678910111213141516171819202122232425РезультатЗапроса = Запрос.Выполнить();ВыборкаНоменклатура = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);Пока ВыборкаНоменклатура.Следующий() Цикл// если услуга, то записываем только регистр ПродажиЕсли НЕ ВыборкаНоменклатура.ЭтоУслуга = Перечисления.ВидыНоменклатуры.Услуга Тогда// контроль остатков по сгруппированным в ИТОГАХ номенклатурным позициямЕсли ВыборкаНоменклатура.Количество > ВыборкаНоменклатура.КоличествоОстаток ТогдаСообщение = Новый СообщениеПользователю;Сообщение.Текст = СтрШаблон("По номенклатуре %1 не хватает %2 шт.",ВыборкаНоменклатура.НоменклатураПредставление,ВыборкаНоменклатура.Количество - ВыборкаНоменклатура.КоличествоОстаток);Сообщение.Сообщить();Отказ = ИСТИНА;КонецЕсли;// если не хватает, то отменяем проведение (детальные записи не обрабатываем)Если Отказ ТогдаПродолжить;КонецЕсли;[свернуть]
- списываем номенклатуру по партиям с контролем "проблемы копеек" и записываем движения в регистр
ОстаткиНоменклатуры
(только, если не Услуга);Код12345678910111213141516171819202122232425262728293031323334353637// списываем номенклатуру по партиямКоличествоВсегоСписать = ВыборкаНоменклатура.Количество;Выборка = ВыборкаНоменклатура.Выбрать();// обходим детальные записи в группах ВыборкаНоменклатураПока Выборка.Следующий() И КоличествоВсегоСписать > 0 Цикл// списываем минимальное из... Выборка.КоличествоОстаток - для учета партииКоличествоСписать = МИН(КоличествоВсегоСписать,Выборка.КоличествоОстаток);// решаем "проблему копеек"Если КоличествоВсегоСписать = Выборка.КоличествоОстаток ТогдаСебестоимостьСписать = Выборка.СебестоимостьОстаток;ИначеСебестоимостьСписать = КоличествоСписать/Выборка.КоличествоОстаток*Выборка.СебестоимостьОстаток;КонецЕсли;Движение = Движения.ОстаткиНоменклатуры.Добавить();Движение.ВидДвижения = ВидДвиженияНакопления.Расход;Движение.Период = Дата;Движение.Номенклатура = Выборка.Номенклатура;Движение.Партия = Выборка.Партия;Движение.Количество = КоличествоСписать;Движение.Себестоимость = СебестоимостьСписать;КоличествоВсегоСписать = КоличествоВсегоСписать - КоличествоСписать;// для регистра ПродажиСписаннаяСебестоимость = СписаннаяСебестоимость + СебестоимостьСписать;КонецЦикла;Иначе// если услуга, то Себестоимость равна 0СебестоимостьСписать = 0;КонецЕсли;[свернуть] - записываем движения в регистр Продажи и взводим флаги на запись;
Код123456789101112// регистр ПродажиДвижение = Движения.Продажи.Добавить();Движение.Период = Дата;Движение.Номенклатура = ВыборкаНоменклатура.Номенклатура;Движение.Количество = ВыборкаНоменклатура.Количество;Движение.Себестоимость = СебестоимостьСписать;Движение.СуммаПродажи = ВыборкаНоменклатура.Сумма;КонецЦикла;Движения.ОстаткиНоменклатуры.Записывать = Истина;Движения.Продажи.Записывать = Истина;[свернуть]
- раскомментировать код блокировки и ввести правильные данные;
Код1234567891011// устанавливаем блокировкуБлокировка = Новый БлокировкаДанных;ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиНоменклатуры");ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;// указываем измерение Склад//ЭлементБлокировки.УстановитьЗначение("Склад", Склад);// указываем источник данных (табличная часть в примере)ЭлементБлокировки.ИсточникДанных = СписокНоменклатуры;// указываем измерение и соответствующую колонку таблицыЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура", "Номенклатура");Блокировка.Заблокировать();[свернуть]
- запросом с обработкой результатов получаем данные для проведения из табличной части и регистра накопления
- Завести пользовательские данные в режиме 1С Предприятие, провести документ, проверить движения (добавить ссылку на соответствующий регистр в форму документа: (три верикальные точки) – Окно – Настройка панели навигации формы).
[свернуть]
Видео https://youtu.be/KoYAofD5qws
- Создать новый отчет
ОтчетПоЗадачеОУ1
, разместить в нужной подсистеме (например, ОУ). - Добавить новый
НаборДанных-запрос
. - В конструкторе запроса:
- добавить таблицу регистр
ПродажиОбороты
; - выбрать из него поля
Номенклатура
,КоличествоОборот
,СебестоимостьОборот
,СуммаПродажиОборот
(для удобства можно переименовать, убрав ...Оборот
); - в параметрах виртуальной таблицы регистра
ПродажиОбороты
указать параметры&НачалоПериода
и&КонецПериода
;
- добавить таблицу регистр
- На вкладке Вычисляемые поля добавить вычисляемое поле
Прибыль
, которое рассчитывается как«Сумма продаж» – «Себестоимость»
(поле Выражение), установить соответствующий заголовок. - Добавить ресурсы (все).
- На вкладке Параметры добавить СтандартныйПериод ;
Рисунок[свернуть]
- На вкладке Настройки добавить в отчет:
-
- новую группировку (детальные записи, не выбирая поле), без иерархии, установить для неё имя
Заголовок
; - внизу выбрать
Отчет
, перейти на вкладку Другие настройки -Выводить параметры
- выбратьНе выводить
; - внизу выбрать
<Детальные записи> (Заголовок)
, перейти на вкладку Другие настройки - (в самый низ) -Вариант использования группировки
- выбратьДополнительная информация
; - новую группировку
Номенклатура
, без иерархии;
- новую группировку (детальные записи, не выбирая поле), без иерархии, установить для неё имя
- вверху на вкладке Макеты добавить заголовок (как в задании):
- добавить макет группировки, выбрать группировку
Заголовок
; - в табличном документе в ячейке размещаем текст заголовка из задания с параметрами ("Продажи за период с [НачалоПериода] по [КонецПериода]"), форматируем шрифт как в задании, связываем эту ячейку с макетом
Заголовок
в полеОбласть
, в свойствах ячейки меняем заполнение наШаблон
; - связываем параметры
[НачалоПериода]
и[КонецПериода]
шаблона с соответствующими параметрами отчета (в папкеПараметрыДанных
); - форматируем вывод даты в свойсвах ячейки (Формат - Дата) как в задании.
- добавить макет группировки, выбрать группировку
-
- Окончательно внешний вид отчета (например, выравнивание в колонках для шапки таблицы и данных в колонках) настраивается в режиме Предприятие через меню "Ещё" - "Изменить вариант" - "Условное оформление".