Код &НаКлиенте Процедура ОсновноеКонтактноеЛицоПриИзменении(Элемент) Если НЕ ПроверитьЗаполнениеРеквизита() Тогда Сообщить("Выбранное контактное лицо, "+Объект.ОсновноеКонтактноеЛицо+",не работает у контрагента."); КонецЕсли; КонецПроцедуры
&НаСервере Функция ПроверитьЗаполнениеРеквизита() Возврат (Объект.ОсновноеКонтактноеЛицо.ПредставительРаботает); КонецФункции &НаСервере Процедура УстановитьНомерПредставителя()
Объект.ТелефонКонтактногоЛица=Объект.ОсновноеКонтактноеЛицо.КонтактныеСведения; КонецПроцедуры При проверке выдает ошибку: {Справочник.Контрагенты.Форма.ФормаСписка.Форма(12,11)}: Переменная не определена (Объект)
работаю на версии 1С:Предприятие 8.3 (8.3.10.2650) |
Оборотные регистры накопления, последовательности, нумераторы, регистры сведений
Займемся теперь кодом модуля РассчитатьНаСервере(). Воспользуемся конструктором запросов с обработкой результатов для того, чтобы перенести сформированный в консоли текст запроса в код модуля.
В итоге задачу заполнения табличной части данными мы решили следующим образом:
&НаКлиенте Процедура РассчитатьСебестоимостьИОстатки(Команда) Режим=РежимДиалогаВопрос.ДаНет; Ответ=Вопрос("Для продолжения нужно записать документ. Сделать это?",Режим,0); Если Ответ=КодВозвратаДиалога.Да Тогда Записать(); РассчитатьНаСервере(); Предупреждение("Табличная часть заполнена"); Иначе Предупреждение("Табличная часть не заполнена"); КонецЕсли; КонецПроцедуры &НаСервере Процедура РассчитатьНаСервере() Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ДокМ.Номенклатура, | ЕСТЬNULL(ОстМ.КоличествоОстаток, 0) КАК КоличествоОстатков, | ЕСТЬNULL(ОстМ.СуммаОстаток, 0) КАК СуммаОстатков, | ДокМ.Количество, | ДокМ.ЦенаПродажи, | ДокМ.Выручка |ИЗ | Документ.РеализацияМатериалов.Материалы КАК ДокМ | ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиМатериалов.Остатки(&МоментВремени, ОтветственныйСотрудник = &ОтвСотр) КАК ОстМ | ПО ДокМ.Номенклатура = ОстМ.Номенклатура |ГДЕ | ДокМ.Ссылка = &Ссылка"; Запрос.УстановитьПараметр("МоментВремени", Объект.Ссылка.МоментВремени()); Запрос.УстановитьПараметр("ОтвСотр", Объект.ОтветственныйСотрудник); Запрос.УстановитьПараметр("Ссылка", Объект.Ссылка); Результат = Запрос.Выполнить(); ВыборкаДетальныеЗаписи = Результат.Выбрать(); Объект.Материалы.Очистить(); Пока ВыборкаДетальныеЗаписи.Следующий() Цикл СтрокаТЧ=Объект.Материалы.Добавить(); СтрокаТЧ.Номенклатура = ВыборкаДетальныеЗаписи.Номенклатура; Если НЕ ВыборкаДетальныеЗаписи.КоличествоОстатков=0 Тогда СтрокаТЧ.Себестоимость=ВыборкаДетальныеЗаписи.СуммаОстатков/ ВыборкаДетальныеЗаписи.КоличествоОстатков; КонецЕсли; СтрокаТЧ.Остаток=ВыборкаДетальныеЗаписи.КоличествоОстатков; СтрокаТЧ.Количество=ВыборкаДетальныеЗаписи.Количество; СтрокаТЧ.ЦенаПродажи=ВыборкаДетальныеЗаписи.ЦенаПродажи; СтрокаТЧ.Выручка=ВыборкаДетальныеЗаписи.Выручка; КонецЦикла; КонецПроцедуры &НаКлиенте Процедура РассчитатьСумму() ТекущаяСтрока=Элементы.Материалы.ТекущиеДанные; ТекущаяСтрока.Выручка=ТекущаяСтрока.Количество*ТекущаяСтрока.ЦенаПродажи; КонецПроцедуры &НаКлиенте Процедура МатериалыКоличествоПриИзменении(Элемент) РассчитатьСумму(); КонецПроцедуры &НаКлиенте Процедура МатериалыЦенаПродажиПриИзменении(Элемент) РассчитатьСумму(); КонецПроцедуры
В методе, работающем на клиенте, мы, сразу после запуска, сообщаем пользователю о том, что для правильной работы системы нужно сначала записать документ. Если он отвечает утвердительно – записываем документ и вызываем серверную процедуру. Для задавания подобных вопросов в виде диалоговых окон с кнопками-вариантами вопроса ( рис. 8.4.), используется метод Вопрос().
В серверной процедуре мы выбираем с помощью запроса данные из табличной части нашего документа и из регистра ОстаткиМатериалов. Когда данные получены, мы просто очищаем табличную часть и заполняем ее снова, теперь уже с использованием новых данных.
В итоге, после того, как пользователь заполнил табличную часть документа и нажал на кнопку Рассчитать себестоимость и остатки, он получит примерно следующее, рис. 8.5.
Поля Остаток и Себестоимость в данном случае играют лишь вспомогательную роль, позволяя пользователю сразу, при заполнении документа, понять, каково состояние дел с остатками материалов.
Форму документа, да и процедуру заполнения, можно дорабатывать и оптимизировать, но свои основные функции они выполняют, поэтому теперь займемся конструированием оборотного регистра накопления, в котором мы собираемся хранить сведения о продажах. А именно, нас интересуют данные о номенклатуре, о контрагенте, об ответственном лице, продавшем материалы, о количестве, себестоимости и цене материалов.
Создадим новый регистр накопления, назовем его Продажи. Вид регистра установим в значение Обороты, рис. 8.6. Включим его в состав подсистемы ОперативныйУчетМатериалов.
В состав данных регистра, рис. 8.7., внесем следующие:
Измерения:
Имя: Контрагент, тип: СправочникСсылка.Контрагенты
Имя: ОтветственныйСотрудник, тип: СправочникСсылка.Сотрудники
Имя: Номенклатура, тип: СправочникСсылка.Номенклатура
Ресурсы:
Имя: Себестоимость, тип: Число, длина 10, точность 2
Имя: Количество, тип: Число, длина 10, точность 3
Имя: Выручка, тип: Число, длина 10, точность 2
В качестве регистратора для данного регистра выберем документ РеализацияМатериалов.
Теперь займемся проведением этого документа. Он должен формировать движения по двум регистрам – по регистру ОстаткиМатериалов, и по регистру Продажи.
Добавим в модуль объекта документа процедуру ОбработкаПроведения. При конструировании этой процедуры мы можем воспользоваться уже отработанными при проведении документа ОтпускМатериаловМастеру механизмами.
Процедура ОбработкаПроведения(Отказ, РежимПроведения) Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ДокМ.Номенклатура, | СУММА(ДокМ.Количество) КАК Количество, | СУММА(ДокМ.Выручка) КАК Выручка, | МАКСИМУМ(ЕСТЬNULL(ОстМ.КоличествоОстаток, 0)) КАК КоличествоОстатков, | МАКСИМУМ(ЕСТЬNULL(ОстМ.СуммаОстаток, 0)) КАК СуммаОстатков |ИЗ | Документ.РеализацияМатериалов.Материалы КАК ДокМ | ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиМатериалов.Остатки(&МоментВремени, ОтветственныйСотрудник = &ОтвСотр) КАК ОстМ | ПО ДокМ.Номенклатура = ОстМ.Номенклатура |ГДЕ | ДокМ.Ссылка = &Ссылка | |СГРУППИРОВАТЬ ПО | ДокМ.Номенклатура"; Запрос.УстановитьПараметр("МоментВремени", МоментВремени()); Запрос.УстановитьПараметр("ОтвСотр", ОтветственныйСотрудник); Запрос.УстановитьПараметр("Ссылка", Ссылка); Результат = Запрос.Выполнить(); ВыборкаДЗ = Результат.Выбрать(); Движения.ОстаткиМатериалов.Записывать=Истина; Движения.Продажи.Записывать=Истина; Пока ВыборкаДЗ.Следующий() Цикл Если ВыборкаДЗ.Количество>ВыборкаДЗ.КоличествоОстатков Тогда Сообщить("Недостаточное количество товара "+ВыборкаДЗ.Номенклатура +", необходимо "+ВыборкаДЗ.Количество+", в наличии " +ВыборкаДЗ.КоличествоОстатков); Отказ=Истина; Движения.ОстаткиМатериалов.Записывать=Ложь; Движения.Продажи.Записывать=Ложь; КонецЕсли; Если Отказ Тогда Продолжить; КонецЕсли; Движение=Движения.ОстаткиМатериалов.Добавить(); Движение.ВидДвижения=ВидДвиженияНакопления.Расход; Движение.Период=Дата; Движение.Номенклатура=ВыборкаДЗ.Номенклатура; Движение.Количество=ВыборкаДЗ.Количество; Движение.Сумма=ВыборкаДЗ.Количество*ВыборкаДЗ.СуммаОстатков/ВыборкаДЗ.КоличествоОстатков; Движение.ОтветственныйСотрудник=ОтветственныйСотрудник; Движение=Движения.Продажи.Добавить(); Движение.Период=Дата; Движение.Номенклатура=ВыборкаДЗ.Номенклатура; Движение.Количество=ВыборкаДЗ.Количество; Движение.Себестоимость=ВыборкаДЗ.Количество*ВыборкаДЗ.СуммаОстатков/ВыборкаДЗ.КоличествоОстатков; Движение.Выручка=ВыборкаДЗ.Выручка; Движение.ОтветственныйСотрудник=ОтветственныйСотрудник; Движение.Контрагент=Покупатель; КонецЦикла; КонецПроцедуры
Так, здесь мы, во-первых, проверим достаточность материалов для списания – ранее заполненная табличная часть, служит лишь подсказкой пользователю, к тому же, он может, в процессе работы, получать сведения об остатках и себестоимости единицы, а может и не получать, оставляя соответствующие поля табличной части пустыми, поэтому при проведении документа мы получим с помощью запроса нужные данные из базы.
Дальше все идет по уже знакомому вам плану – мы сверяем количество материалов, которое пользователь хочет продать с количеством остатков и принимаем решение либо о продолжении работы, либо – об отмене процедуры проведения документа.
После того, как у нас есть хранилище данных о продажах, мы построим соответствующий отчет. На базе тех данных, которые у нас есть, можно построить различные отчеты – все зависит от того, какие именно данные нас интересуют. Предположим, мы заинтересованы в сведениях о продажах по контрагентам. Нас интересует количественный показатель продажи номенклатурной позиции и прибыль от продажи.