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

Проведение расходного документа, журналы документов, программная работа с документами

< Лекция 7 || Лекция 8: 12345 || Лекция 9 >

Скопируем полученный текст запроса в буфер обмена и перейдем в Конфигуратор. В процедуре ОбработкаПроведения документа ОтпускМатериаловМастеру. Процедура пока пуста, щелкнем в ней правой кнопкой мыши и вызовем из контекстного меню команду Конструктор запроса с обработкой результата. В ответ на вопрос конструктора о создании нового запроса, ответим утвердительно, после чего, в окне конструктора нажмем на кнопку Запрос и вставим в пустое поле для текста запроса полученный текст запроса (предварительно нажав на кнопку Редактировать запрос в окне Запрос), рис. 7.3.

Добавление сформированного текста запроса в конструктор

увеличить изображение
Рис. 7.3. Добавление сформированного текста запроса в конструктор

На закладке Обработка окна Конструктор запроса оставим переключатель Тип обработки в положении Обход результата. После закрытия окна Запрос конструктор автоматически разберет запрос, "разложит" по закладкам своего окна, при необходимости, его можно будет редактировать, пользуясь инструментами, расположенными на этих закладках. Нас запрос устраивает – поэтому мы можем нажимать в окне конструктора ОК и переходить к дальнейшему редактированию кода, рис. 7.4.

Добавление сформированного текста запроса в конструктор

увеличить изображение
Рис. 7.4. Добавление сформированного текста запроса в конструктор

Здесь нас, в первую очередь, не устраивает автоматическое заполнение параметров запроса

Заменим код:

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

На код:

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

Здесь мы, во-первых, вызвали метод МоментВремени(), возвращающий момент времени для нашего документа (то есть – для того, в модуле объекта которого мы сейчас работаем). Во-вторых, мы обратились к реквизиту документа ОтветственныйСотрудник для установки параметра ОтвСотр.

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

Анализ результата выполнения запроса в коде процедуры проведения документа

увеличить изображение
Рис. 7.5. Анализ результата выполнения запроса в коде процедуры проведения документа

Здесь мы выполнили метод Выгрузить() для результата выполнения запроса (переменная Результат), получили таблицу значений, которую можно проанализировать. Результат нас устраивает, поэтому мы принимаемся за дальнейшую работу над процедурой. В итоге у нас получился следующий код:

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

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

  Результат = Запрос.Выполнить();

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

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

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

Сначала мы сравнили требуемое и реальное количество материалов. Если нужно больше, чем имеется за конкретным ответственным лицом, мы формируем сообщение для пользователя, устанавливаем параметр Отказ в значение Истина (то есть указываем системе на то, что документ мы проводить не будем), и отключаем запись данных в регистр накопления. После проверки количества мы выполняем еще одну проверку – на состояние переменной Отказ. Если эта переменная установлена в значение Истина – мы переходим к следующей итерации цикла, не выполняя оставшиеся команды. Если же Отказ установлен в значение Ложь, мы формируем запись по регистру ОстаткиМатериалов с использованием текущих данных. Обратите внимание на то, как рассчитывается поле Сумма – для его получения мы умножаем количество материалов, которые нужно списать, на результат деления общей суммы остатков материалов на общее количество остатков.

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

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

< Лекция 7 || Лекция 8: 12345 || Лекция 9 >
Лариса Дятчина
Лариса Дятчина

Код 

&НаКлиенте

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

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

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

КонецЕсли;

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

 

&НаСервере

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

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

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

&НаСервере

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

 

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

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

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

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

 

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

максим матасов
максим матасов