Уважаемые программисты, прошу помогите, пожалуйста.
Есть расходная накладная с реквизитами: Контрагент, Склад, ВидЦены, ТЧРасхНакл с реквизитами: ТМЦ, Цена, Количество, Сумма, УчЦена, УчСумма. И есть регистр накопления ТМЦ с измерениями ТМЦ, Склад и ресурсами Количество, Сумма.
Необходимо рассчитать УчЦену и УчСумму при проведении расходной накладной по дате.
Я в 1с вообще мало, что знаю. Пыталась делать сама. Из того, что нашла поняла, что нужно сначала в модуле объекта Процедура ПередЗаписью получить запросом остатки по количеству и сумме, а потом в Процедуре ОбработкаПроведения посчитать уч. цену и уч. сумму используя временные таблицы.
Запрос я сделала, остатки получила, а вот что и как нужно делать с временными таблицами вообще понять не могу.
До последнего не хотела никого напрягать, думала сама разберусь. Не получается((
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
Для Каждого СтрТЧ ИЗ ТЧРасхНакл Цикл
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ТМЦОстатки.КоличествоОстаток,
| ТМЦОстатки.СуммаОстаток,
| ВЫРАЗИТЬ (ЕСТЬNULL(ТМЦОстатки.СуммаОстаток, 0) / ЕСТЬNULL(ТМЦОстатки.КоличествоОстаток, 1) КАК ЧИСЛО(15,2)) КАК УчЦена
|ИЗ
| РегистрНакопления.ТМЦ.Остатки(&Дата, ) КАК ТМЦОстатки
|ГДЕ
| ТМЦОстатки.ТМЦ = &ТМЦ
| И ТМЦОстатки.Склад = &Склад";
Запрос.УстановитьПараметр("ТМЦ",СтрТЧ.ТМЦ);
Запрос.УстановитьПараметр("Склад", Склад);
Запрос.УстановитьПараметр("Дата", Дата);
Результат = Запрос.Выполнить();
ВыборкаИзЗапроса = Результат.Выбрать();
Если ВыборкаИзЗапроса.Следующий() Тогда
Если СтрТЧ.Количество > ВыборкаИзЗапроса.КоличествоОстаток Тогда
Сообщить("Товара "+СтрТЧ.ТМЦ +" не хватает на складе");
Отказ = Истина;
КонецЕсли;
Иначе
Сообщить("Товара "+СтрТЧ.ТМЦ +" нет на складе");
Отказ = Истина;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Проверка на остаток лучше делать в процедуре "ОбработкаПроведения".
Вообще, запрос в цикле для проверки остатка (и вобще) это мягко говоря не красиво.
я бы проверил остатки тех товаров которые в документе так:
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
Запрос = Новый Запрос;
Запрос.Текст=
"ВЫБРАТЬ
| РасходнаяНакладнаяТЧРасхНакл.ТМЦ,
| СУММА(РасходнаяНакладнаяТЧРасхНакл.Количество) КАК Количество
|ПОМЕСТИТЬ ТоварыДок
|ИЗ
| Документ.РасходнаяНакладная.ТЧРасхНакл КАК РасходнаяНакладнаяТЧРасхНакл
|ГДЕ
| РасходнаяНакладнаяТЧРасхНакл.Ссылка = &Ссылка
|
|СГРУППИРОВАТЬ ПО
| РасходнаяНакладнаяТЧРасхНакл.ТМЦ
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ТоварыДок.ТМЦ,
| ЕСТЬNULL(ТМЦОстатки.КоличествоОстаток, 0) КАК КоличествоОстаток,
| ТоварыДок.Количество
|ИЗ
| ТоварыДок КАК ТоварыДок
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТМЦ.Остатки(
| &Дата,
| ТМЦ В
| (ВЫБРАТЬ
| ТоварыДок.ТМЦ
| ИЗ
| ТоварыДок КАК ТоварыДок)) КАК ТМЦОстатки
| ПО ТоварыДок.ТМЦ = ТМЦОстатки.ТМЦ";
Запрос.УстановитьПараметр("Ссылка", Ссылка);
Запрос.УстановитьПараметр("Дата", Дата);
Результат = Запрос.Выполнить();
ВыборкаИзЗапроса = Результат.Выбрать();
Пока ВыборкаИзЗапроса.Следующий() Цикл
Если ВыборкаИзЗапроса.Количество > ВыборкаИзЗапроса.КоличествоОстаток Тогда
Сообщить("Товара "+ВыборкаИзЗапроса.ТМЦ +" не хватает на складе");
Отказ = Истина;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
ну по заданию заполнить в табличной части накладной два последних поля, а для чего я если честно не знаю. Я что в бухгалтерии, что в 1с мягко сказать не разбираюсь
Спасибо большое, что вы откликнулись))
А то я уже в отчаянии((
Извините, а Вы не могли бы объяснить, что такое Левое соединение?
Если я правильно понимаю, то Вы запросом по каждому товару определяете суммарное количество и записываете в временную таблицу, потом в этой таблице уже определяете остатки по количеству и что потом происходит? Остатки из временной таблицы переносятся в остатки регистра накопления ТМЦОстатки или что((?
Если Вам не сложно, можете изменить созданный запрос, что бы в поля табличной части (ТЧРасхНакл) УчЦена и УчСумма заполнились при проведении. Я понимаю, что это наглешь и что Вы и так потратили свое время и помогли, но просто я ВООБЩЕ не знаю что и куда. Пожалуйста.
Я когда перечитываю, что пишу, понимаю, что написала какую то ахинею и знающий человек наверняка просто в шоке с того, какие есть бестолковые люди((
та я не против, Вы понимаете, мне дали задание. Дословно: организовать расчет учетных цен при проведении расходной накладной по дате.
Перед этим было задание создать расх. накладную (еще пока без полей уч. цена и уч. сумма) и провести его по регистру накопления ТМЦ, что я и сделала.
Потом, задание усложнили: добавить в табл часть ТЧРасхНакл 2 поля - уч. цена и уч. сумма, посчитать эти значения при новом проведении того же, уже проведенного, документа. Хорошо вы говорите, что это не правильно так делать и нужно перед тем как записывать посчитать, а потом уже проводить. А как, как это сделать?
Проблема вся в том, что я не знаю как сделать не при проведении, ни при перед записью. Никак((
Из того запроса при проведении, которое мне скинули пере Вами, как теперь уч.цену и уч. сумму найти и записать?
или этот запрос при условии что будут считаться уч. цены и уч. суммы ПередЗаписью не подходит?
Спасибо, спасибо, спасибо Вам огромное, что Вы такой отзывчивый человек, что помогаете таким бестолковым как я)). Когда оно заработало очень обрадовалось, теперь осталось разобрать что к чему и что куда))
а можете еще ответить, если в расходной накладной первая запись ручка и вторая запись ручка, то почему учетная цена и сумма записывается только в поле там,где первая запись ручка, а в следующей нету ничего))
Это вопрос к 1сnovice))
и это по первому предложенному варианту
А во втором ошибку выдает((
Ошибка при выполнении обработчика - 'ПередЗаписью'
по причине:
{Документ.РасходнаяНакладная.МодульОбъекта(50)}: Значение не является значением объектного типа (УчЦена)
ТоварВТЧ.УчЦена = УчЦена;
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
Запрос = Новый Запрос;
Запрос.Текст=
"ВЫБРАТЬ
| РасходнаяНакладнаяТЧРасхНакл.ТМЦ,
| СУММА(РасходнаяНакладнаяТЧРасхНакл.Количество) КАК Количество
|ПОМЕСТИТЬ ТоварыДок
|ИЗ
| Документ.РасходнаяНакладная.ТЧРасхНакл КАК РасходнаяНакладнаяТЧРасхНакл
|ГДЕ
| РасходнаяНакладнаяТЧРасхНакл.Ссылка = &Ссылка
|
|СГРУППИРОВАТЬ ПО
| РасходнаяНакладнаяТЧРасхНакл.ТМЦ
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ТоварыДок.ТМЦ,
| ЕСТЬNULL(ТМЦОстатки.КоличествоОстаток, 0) КАК КоличествоОстаток,
| ТоварыДок.Количество
|ИЗ
| ТоварыДок КАК ТоварыДок
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТМЦ.Остатки(
| &Дата,
| ТМЦ В
| (ВЫБРАТЬ
| ТоварыДок.ТМЦ
| ИЗ
| ТоварыДок КАК ТоварыДок)
| И Склад = &Склад) КАК ТМЦОстатки
| ПО ТоварыДок.ТМЦ = ТМЦОстатки.ТМЦ";
Запрос.УстановитьПараметр("Ссылка", Ссылка);
Запрос.УстановитьПараметр("Дата", Дата);
Запрос.УстановитьПараметр("Склад", Склад);
Результат = Запрос.Выполнить();
ВыборкаИзЗапроса = Результат.Выбрать();
Пока ВыборкаИзЗапроса.Следующий() Цикл
Если ВыборкаИзЗапроса.Количество > ВыборкаИзЗапроса.КоличествоОстаток Тогда
Сообщить("Товара "+ВыборкаИзЗапроса.ТМЦ +" не хватает на складе");
Отказ = Истина;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
Если НЕ(РежимЗаписи = РежимЗаписиДокумента.Проведение) Тогда
Возврат;
КонецЕсли;
Запрос = Новый Запрос;
Запрос.Текст=
"ВЫБРАТЬ
| РасходнаяНакладнаяТЧРасхНакл.ТМЦ
|ПОМЕСТИТЬ ТоварыДок
|ИЗ
| Документ.РасходнаяНакладная.ТЧРасхНакл КАК РасходнаяНакладнаяТЧРасхНакл
|ГДЕ
| РасходнаяНакладнаяТЧРасхНакл.Ссылка = &Ссылка
|
|СГРУППИРОВАТЬ ПО
| РасходнаяНакладнаяТЧРасхНакл.ТМЦ
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ТоварыДок.ТМЦ,
| ЕСТЬNULL(ТМЦОстатки.СуммаОстаток, 0) КАК СуммаОстаток,
| ЕСТЬNULL(ТМЦОстатки.КоличествоОстаток, 0) КАК КоличествоОстаток
|ИЗ
| ТоварыДок КАК ТоварыДок
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТМЦ.Остатки(
| &Дата,
| ТМЦ В
| (ВЫБРАТЬ
| ТоварыДок.ТМЦ
| ИЗ
| ТоварыДок КАК ТоварыДок)
| И Склад = &Склад) КАК ТМЦОстатки
| ПО ТоварыДок.ТМЦ = ТМЦОстатки.ТМЦ";
Запрос.УстановитьПараметр("Дата", Дата);
Запрос.УстановитьПараметр("Склад", Склад);
Запрос.УстановитьПараметр("Ссылка", Ссылка);
Результат = Запрос.Выполнить();
ВыборкаИзЗапроса = Результат.Выбрать();
Отбор = Новый Структура;
Пока ВыборкаИзЗапроса.Следующий() Цикл
Отбор.Вставить("ТМЦ", ВыборкаИзЗапроса.ТМЦ);
МассивВозможныхДублей = ТЧРасхНакл.НайтиСтроки(Отбор);
Для Каждого Товар Из МассивВозможныхДублей Цикл
Если ВыборкаИзЗапроса.КоличествоОстаток = 0 Тогда
УчЦена = 0;
Иначе
УчЦена = ВыборкаИзЗапроса.СуммаОстаток/ВыборкаИзЗапроса.КоличествоОстаток;
КонецЕсли;
Товар.УчЦена = УчЦена;
Товар.УчСумма = ВыборкаИзЗапроса.СуммаОстаток;
КонецЦикла;
Отбор.Очистить();
КонецЦикла;
КонецПроцедуры
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
Если НЕ(РежимЗаписи = РежимЗаписиДокумента.Проведение) Тогда
Возврат;
КонецЕсли;
Запрос = Новый Запрос;
Запрос.Текст=
"ВЫБРАТЬ
| ТоварыДок.ТМЦ
|ПОМЕСТИТЬ ТоварыДок
|ИЗ &ТоварыДок КАК ТоварыДок
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ТоварыДок.ТМЦ,
| ЕСТЬNULL(ТМЦОстатки.СуммаОстаток, 0) КАК СуммаОстаток,
| ЕСТЬNULL(ТМЦОстатки.КоличествоОстаток, 0) КАК КоличествоОстаток
|ИЗ
| ТоварыДок КАК ТоварыДок
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТМЦ.Остатки(
| &Дата,
| ТМЦ В
| (ВЫБРАТЬ
| ТоварыДок.ТМЦ
| ИЗ
| ТоварыДок КАК ТоварыДок)
| И Склад = &Склад) КАК ТМЦОстатки
| ПО ТоварыДок.ТМЦ = ТМЦОстатки.ТМЦ";
Запрос.УстановитьПараметр("ТоварыДок", ТЧРасхНакл);
Запрос.УстановитьПараметр("Дата", Дата);
Запрос.УстановитьПараметр("Склад", Склад);
Результат = Запрос.Выполнить();
ВыборкаИзЗапроса = Результат.Выбрать();
Отбор = Новый Структура;
Пока ВыборкаИзЗапроса.Следующий() Цикл
Отбор.Вставить("ТМЦ", ВыборкаИзЗапроса.ТМЦ);
МассивВозможныхДублей = ТЧРасхНакл.НайтиСтроки(Отбор);
Для Каждого Товар Из МассивВозможныхДублей Цикл
Если ВыборкаИзЗапроса.КоличествоОстаток = 0 Тогда
УчЦена = 0;
Иначе
УчЦена = ВыборкаИзЗапроса.СуммаОстаток/ВыборкаИзЗапроса.КоличествоОстаток;
КонецЕсли;
Товар.УчЦена = УчЦена;
Товар.УчСумма = ВыборкаИзЗапроса.СуммаОстаток;
КонецЦикла;
Отбор.Очистить();
КонецЦикла;
КонецПроцедуры
Да работает, только значения уч. цен записываются после 2-го проведения документа. С чем это может быть связано?
Большое спасибо, я уже где то 2-ю неделю с этим заданием мучаюсь, а вы так с ним расправились быстро)) Надеюсь, что в будущем я тоже смогу помогать другим)
Спасибо!
А можно, если что то будет не понятно по этому коду, спросить?
Все равно первое проведение первого документа срабатывает со 2-го раза.
А все последующие документы срабатывают сразу
Все работает, извините))
Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7
https://pro1c.org.ua