Опубликован: 06.12.2011 | Уровень: для всех | Доступ: платный
Лекция 9:

Оборотные регистры накопления, последовательности, нумераторы, регистры сведений

Займемся теперь кодом модуля РассчитатьНаСервере(). Воспользуемся конструктором запросов с обработкой результатов для того, чтобы перенести сформированный в консоли текст запроса в код модуля.

В итоге задачу заполнения табличной части данными мы решили следующим образом:

&НаКлиенте
Процедура РассчитатьСебестоимостьИОстатки(Команда)
  Режим=РежимДиалогаВопрос.ДаНет;
  Ответ=Вопрос("Для продолжения нужно записать документ. Сделать это?",Режим,0);
  Если Ответ=КодВозвратаДиалога.Да Тогда
    Записать();
    РассчитатьНаСервере();
    Предупреждение("Табличная часть заполнена");
  Иначе
    Предупреждение("Табличная часть не заполнена");
  КонецЕсли;
КонецПроцедуры

&НаСервере
Процедура РассчитатьНаСервере()
  Запрос = Новый Запрос;
  Запрос.Текст = 
    "ВЫБРАТЬ
    |  ДокМ.Номенклатура,
    |  ЕСТЬNULL(ОстМ.КоличествоОстаток, 0) КАК КоличествоОстатков,
    |  ЕСТЬNULL(ОстМ.СуммаОстаток, 0) КАК СуммаОстатков,
    |  ДокМ.Количество,
    |  ДокМ.ЦенаПродажи,
    |  ДокМ.Выручка
        |ИЗ
    |  Документ.РеализацияМатериалов.Материалы КАК ДокМ
    |    ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиМатериалов.Остатки(&МоментВремени, ОтветственныйСотрудник = &ОтвСотр) КАК ОстМ
    |    ПО ДокМ.Номенклатура = ОстМ.Номенклатура
    |ГДЕ
    |  ДокМ.Ссылка = &Ссылка";

  Запрос.УстановитьПараметр("МоментВремени", Объект.Ссылка.МоментВремени());
  Запрос.УстановитьПараметр("ОтвСотр", Объект.ОтветственныйСотрудник);
  Запрос.УстановитьПараметр("Ссылка", Объект.Ссылка);

  Результат = Запрос.Выполнить();
  
  ВыборкаДетальныеЗаписи = Результат.Выбрать();
  
  Объект.Материалы.Очистить();

  Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
    СтрокаТЧ=Объект.Материалы.Добавить();
    СтрокаТЧ.Номенклатура = ВыборкаДетальныеЗаписи.Номенклатура;
    Если НЕ  ВыборкаДетальныеЗаписи.КоличествоОстатков=0 Тогда
      СтрокаТЧ.Себестоимость=ВыборкаДетальныеЗаписи.СуммаОстатков/
      ВыборкаДетальныеЗаписи.КоличествоОстатков;
    КонецЕсли;
    СтрокаТЧ.Остаток=ВыборкаДетальныеЗаписи.КоличествоОстатков;
    СтрокаТЧ.Количество=ВыборкаДетальныеЗаписи.Количество;
    СтрокаТЧ.ЦенаПродажи=ВыборкаДетальныеЗаписи.ЦенаПродажи;
    СтрокаТЧ.Выручка=ВыборкаДетальныеЗаписи.Выручка;
  КонецЦикла;
КонецПроцедуры

&НаКлиенте
Процедура РассчитатьСумму()
  ТекущаяСтрока=Элементы.Материалы.ТекущиеДанные;
  ТекущаяСтрока.Выручка=ТекущаяСтрока.Количество*ТекущаяСтрока.ЦенаПродажи;
КонецПроцедуры

&НаКлиенте
Процедура МатериалыКоличествоПриИзменении(Элемент)
  РассчитатьСумму();
КонецПроцедуры

&НаКлиенте
Процедура МатериалыЦенаПродажиПриИзменении(Элемент)
  РассчитатьСумму();
КонецПроцедуры

В методе, работающем на клиенте, мы, сразу после запуска, сообщаем пользователю о том, что для правильной работы системы нужно сначала записать документ. Если он отвечает утвердительно – записываем документ и вызываем серверную процедуру. Для задавания подобных вопросов в виде диалоговых окон с кнопками-вариантами вопроса ( рис. 8.4.), используется метод Вопрос().

Вопрос пользователю

Рис. 8.4. Вопрос пользователю

В серверной процедуре мы выбираем с помощью запроса данные из табличной части нашего документа и из регистра ОстаткиМатериалов. Когда данные получены, мы просто очищаем табличную часть и заполняем ее снова, теперь уже с использованием новых данных.

В итоге, после того, как пользователь заполнил табличную часть документа и нажал на кнопку Рассчитать себестоимость и остатки, он получит примерно следующее, рис. 8.5.

Результат автоматического заполнения табличной части

увеличить изображение
Рис. 8.5. Результат автоматического заполнения табличной части

Поля Остаток и Себестоимость в данном случае играют лишь вспомогательную роль, позволяя пользователю сразу, при заполнении документа, понять, каково состояние дел с остатками материалов.

Форму документа, да и процедуру заполнения, можно дорабатывать и оптимизировать, но свои основные функции они выполняют, поэтому теперь займемся конструированием оборотного регистра накопления, в котором мы собираемся хранить сведения о продажах. А именно, нас интересуют данные о номенклатуре, о контрагенте, об ответственном лице, продавшем материалы, о количестве, себестоимости и цене материалов.

Создадим новый регистр накопления, назовем его Продажи. Вид регистра установим в значение Обороты, рис. 8.6. Включим его в состав подсистемы ОперативныйУчетМатериалов.

Создание регистра накопления

Рис. 8.6. Создание регистра накопления

В состав данных регистра, рис. 8.7., внесем следующие:

Измерения:

Имя: Контрагент, тип: СправочникСсылка.Контрагенты

Имя: ОтветственныйСотрудник, тип: СправочникСсылка.Сотрудники

Имя: Номенклатура, тип: СправочникСсылка.Номенклатура

Ресурсы:

Имя: Себестоимость, тип: Число, длина 10, точность 2

Имя: Количество, тип: Число, длина 10, точность 3

Имя: Выручка, тип: Число, длина 10, точность 2

Настройка данных регистра накопления

Рис. 8.7. Настройка данных регистра накопления

В качестве регистратора для данного регистра выберем документ РеализацияМатериалов.

Теперь займемся проведением этого документа. Он должен формировать движения по двум регистрам – по регистру ОстаткиМатериалов, и по регистру Продажи.

Добавим в модуль объекта документа процедуру ОбработкаПроведения. При конструировании этой процедуры мы можем воспользоваться уже отработанными при проведении документа ОтпускМатериаловМастеру механизмами.

Процедура ОбработкаПроведения(Отказ, РежимПроведения)
  Запрос = Новый Запрос;
  Запрос.Текст = 
    "ВЫБРАТЬ
    |  ДокМ.Номенклатура,
    |  СУММА(ДокМ.Количество) КАК Количество,
    |  СУММА(ДокМ.Выручка) КАК Выручка,
    |  МАКСИМУМ(ЕСТЬNULL(ОстМ.КоличествоОстаток, 0)) КАК КоличествоОстатков,
    |  МАКСИМУМ(ЕСТЬNULL(ОстМ.СуммаОстаток, 0)) КАК СуммаОстатков
    |ИЗ
    |  Документ.РеализацияМатериалов.Материалы КАК ДокМ
    |    ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиМатериалов.Остатки(&МоментВремени, ОтветственныйСотрудник = &ОтвСотр) КАК ОстМ
    |    ПО ДокМ.Номенклатура = ОстМ.Номенклатура
    |ГДЕ
    |  ДокМ.Ссылка = &Ссылка
    |
    |СГРУППИРОВАТЬ ПО
    |  ДокМ.Номенклатура";

  Запрос.УстановитьПараметр("МоментВремени", МоментВремени());
  Запрос.УстановитьПараметр("ОтвСотр", ОтветственныйСотрудник);
  Запрос.УстановитьПараметр("Ссылка", Ссылка);

  Результат = Запрос.Выполнить();
  ВыборкаДЗ = Результат.Выбрать();
  Движения.ОстаткиМатериалов.Записывать=Истина;
  Движения.Продажи.Записывать=Истина;

  Пока ВыборкаДЗ.Следующий() Цикл
    Если ВыборкаДЗ.Количество>ВыборкаДЗ.КоличествоОстатков Тогда
      Сообщить("Недостаточное количество товара "+ВыборкаДЗ.Номенклатура
      +", необходимо "+ВыборкаДЗ.Количество+", в наличии "
      +ВыборкаДЗ.КоличествоОстатков);
      Отказ=Истина;
      Движения.ОстаткиМатериалов.Записывать=Ложь;
      Движения.Продажи.Записывать=Ложь;
    КонецЕсли;
    
    Если Отказ Тогда
      Продолжить;
    КонецЕсли;
    
    Движение=Движения.ОстаткиМатериалов.Добавить();
    Движение.ВидДвижения=ВидДвиженияНакопления.Расход;
    Движение.Период=Дата;
    Движение.Номенклатура=ВыборкаДЗ.Номенклатура;
    Движение.Количество=ВыборкаДЗ.Количество;
    Движение.Сумма=ВыборкаДЗ.Количество*ВыборкаДЗ.СуммаОстатков/ВыборкаДЗ.КоличествоОстатков;
    Движение.ОтветственныйСотрудник=ОтветственныйСотрудник;
        
    Движение=Движения.Продажи.Добавить();
    Движение.Период=Дата;
    Движение.Номенклатура=ВыборкаДЗ.Номенклатура;
    Движение.Количество=ВыборкаДЗ.Количество;
    Движение.Себестоимость=ВыборкаДЗ.Количество*ВыборкаДЗ.СуммаОстатков/ВыборкаДЗ.КоличествоОстатков;
    Движение.Выручка=ВыборкаДЗ.Выручка;
    Движение.ОтветственныйСотрудник=ОтветственныйСотрудник;
    Движение.Контрагент=Покупатель;
  КонецЦикла;
КонецПроцедуры

Так, здесь мы, во-первых, проверим достаточность материалов для списания – ранее заполненная табличная часть, служит лишь подсказкой пользователю, к тому же, он может, в процессе работы, получать сведения об остатках и себестоимости единицы, а может и не получать, оставляя соответствующие поля табличной части пустыми, поэтому при проведении документа мы получим с помощью запроса нужные данные из базы.

Дальше все идет по уже знакомому вам плану – мы сверяем количество материалов, которое пользователь хочет продать с количеством остатков и принимаем решение либо о продолжении работы, либо – об отмене процедуры проведения документа.

После того, как у нас есть хранилище данных о продажах, мы построим соответствующий отчет. На базе тех данных, которые у нас есть, можно построить различные отчеты – все зависит от того, какие именно данные нас интересуют. Предположим, мы заинтересованы в сведениях о продажах по контрагентам. Нас интересует количественный показатель продажи номенклатурной позиции и прибыль от продажи.

Лариса Дятчина
Лариса Дятчина

Код 

&НаКлиенте

Процедура ОсновноеКонтактноеЛицоПриИзменении(Элемент)

Если НЕ ПроверитьЗаполнениеРеквизита() Тогда

 Сообщить("Выбранное контактное лицо, "+Объект.ОсновноеКонтактноеЛицо+",не работает у контрагента.");

КонецЕсли;

КонецПроцедуры

 

&НаСервере

Функция ПроверитьЗаполнениеРеквизита()

 Возврат (Объект.ОсновноеКонтактноеЛицо.ПредставительРаботает);  

КонецФункции

&НаСервере

Процедура УстановитьНомерПредставителя()

 

 Объект.ТелефонКонтактногоЛица=Объект.ОсновноеКонтактноеЛицо.КонтактныеСведения;

КонецПроцедуры

При проверке выдает ошибку:

{Справочник.Контрагенты.Форма.ФормаСписка.Форма(12,11)}: Переменная не определена (Объект)
 Возврат (<<?>>Объект.ОсновноеКонтактноеЛицо.ПредставительРаботает);   (Проверка: Сервер)
{Справочник.Контрагенты.Форма.ФормаСписка.Форма(17,2)}: Переменная не определена (Объект)
 <<?>>Объект.ТелефонКонтактногоЛица=Объект.ОсновноеКонтактноеЛицо.КонтактныеСведения; (Проверка: Сервер)
{Справочник.Контрагенты.Форма.ФормаСписка.Форма(17,32)}: Переменная не определена (Объект)
 Объект.ТелефонКонтактногоЛица=<<?>>Объект.ОсновноеКонтактноеЛицо.КонтактныеСведения; (Проверка: Сервер)
{Справочник.Контрагенты.Форма.ФормаСписка.Форма(6,41)}: Переменная не определена (Объект)
 Сообщить("Выбранное контактное лицо, "+<<?>>Объект.ОсновноеКонтактноеЛицо+",не работает у контрагента."); (Проверка: Тонкий клиент)

 

работаю на версии 1С:Предприятие 8.3 (8.3.10.2650)

максим матасов
максим матасов
Леонид Альбрехт
Леонид Альбрехт
Россия, Екатеринбург, 10, 2004
Оксана Максимова
Оксана Максимова
Россия, Екатеринбург, Уральский государственный университет им. А. М. Горького, 1995