Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Нужна помощь в работе с запросами
Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7 > Программисту > Программирование в 1С Предприятие 8.1 (8.0)
Страницы: 1, 2
Vofka
Пока отбой. Заметил бок в проведении ПН. Разберусь - отпишу.
World1С
ВЫБРАТЬ
    РасходнаяНакладнаяРасход.Номенклатура,
    ПартииОстатки.КоличествоОстаток
ИЗ
    Документ.РасходнаяНакладная.Расход КАК РасходнаяНакладнаяРасход
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Партии.Остатки(
                ,
                Номенклатура В
                    (ВЫБРАТЬ
                        РасходнаяНакладнаяРасход.Номенклатура
                    ИЗ
                        Документ.РасходнаяНакладная.Расход КАК РасходнаяНакладнаяРасход
                    ГДЕ
                        РасходнаяНакладнаяРасход.Ссылка = &Документ)) КАК ПартииОстатки
        ПО РасходнаяНакладнаяРасход.Номенклатура = ПартииОстатки.Номенклатура
ГДЕ
    РасходнаяНакладнаяРасход.Ссылка = &Документ
    И (ПартииОстатки.КоличествоОстаток < РасходнаяНакладнаяРасход.Количество
            ИЛИ ПартииОстатки.КоличествоОстаток ЕСТЬ NULL )


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


"Еще один момент в документе может оказаться несколько строчек с одинаковым товаром. Тогда переделаем запрос" эта цитата с диска ИТС
Vofka
Пока смотрю... Но сразу ворос: что делает "В" (Номенклатура В)? Если можно - приведите пример.

ЗЫ. Я почти получил такой запрос как мне надо:


Одно НО! Почему задваивается КоличествоВДокументе? sad.gif
World1С
Цитата
что делает "В"


Эта конструкция означает (в списке значений)

Т.е. в нашем примере список номенклатуры в табличной части "Расход"
World1С
Убери регистр партии оставь только партии.остаток
Vofka
Цитата
Убери регистр партии оставь только партии.остаток


Как я без регистра партии узнаю сколько осталось по каждой партии? При списании по ФИФО (мне надо) надо ж как-то рассчитать цену списания. А как я это сделаю? При методе списания по среднему - можно без регистра партии, а как тут без него обойтись - хз.

Ещё раз повторяю: мне надо сделать партионный учет по методу ФИФО. Запросы мои могут быть не правильные (по логике), но уж очень я хочу разобраться! 64000000.gif

Цитата
список номенклатуры в табличной части "Расход"


А можно на пальцах? blush.gif

К стати, какова цель: написать 1 запрос, который бы отбирал нужные данные для списания по ФИФО.
Fynjy
Что то вы мудрите ...
ВЫБРАТЬ
ТоварыНаСкладахОстаткиИОбороты.Регистратор КАК Регистратор,
ТоварыНаСкладахОстаткиИОбороты.КоличествоКонечныйОстаток
ИЗ
РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(, , Регистратор, , ) КАК ТоварыНаСкладахОстаткиИОбороты

УПОРЯДОЧИТЬ ПО
Регистратор
Fynjy
Если лифо добавте в запрос убыв ...
World1С
Цитата
Как я без регистра


У тебя есть виртуальная таблица Партии.Остатки
Vofka
Цитата
Что то вы мудрите ...
ВЫБРАТЬ
ТоварыНаСкладахОстаткиИОбороты.Регистратор КАК Регистратор,
ТоварыНаСкладахОстаткиИОбороты.КоличествоКонечныйОстаток
ИЗ
РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(, , Регистратор, , ) КАК ТоварыНаСкладахОстаткиИОбороты

УПОРЯДОЧИТЬ ПО
Регистратор


А у меня вообще регистратор не выбирается. Его даже в списке таблиц нету.


Цитата
тебя есть виртуальная таблица Партии.Остатки


Есть. Но там нету регистратора (партии)!
Fynjy
Кнопка параметры виртуальных таблиц ...
Vofka
И что мне дает этот запрос?
Сделал так:

но не пойму как эти данные использовать 19000000.gif

ЗЫ. моск взорван icon_revenant7.gif
World1С
Ну, говорил же что одним запросом все это сделать очень сложно, лучше работать с результатом запроса....
Vofka
Подробней можно?
Fynjy
Списание по партиям
1. Получить список партий - запрос
2. Цикл пока списываемое количество > количества остатка партии
Все ...
World1С
+ 100 Fynjy

1.То что у тебя в результате запроса вставь в цикл
2.
Цикл пока списываемое количество > количества остатка партии

3. Внутри цикла делаем движения расход по регистру партии товара
вомбат


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

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

РезультатЗапроса = Запрос.Выполнить();
ВыборкаТоваров = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам, "Номенклатура");

Пока ВыборкаТоваров.Следующий() Цикл
Остаток = ВыборкаТоваров.КолОст;
КолДок = ВыборкаТоваров.КолДок;
СуммаДок = ВыборкаТоваров.СуммаДок;

Нехватка = КолДок - Остаток;
Если Нехватка > 0 Тогда
Сообщить("Нехватка товара " + СокрЛП(ВыборкаТоваров.Номенклатура) + " на складе " + СокрЛП(Склад) + ": " + Нехватка);
Сообщить("Расходная накладная " + Номер + " от " + Дата + " не проводится!");
Отказ = Истина;
КонецЕсли;

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


Примерно так будет работать.
вомбат
Чуть не забыл. Регистр партий нужно поправить - добавить измерение "Партия", ну и движения ПН тоже подправить.
Vofka
ВОМБАТ, с добавлением к регистру партии нового измерения - я получил результат запроса какой хотел smile.gif



Но теперь я не знаю как мне его использовать sad.gif . Как знать, что в выборке я перешёл к следующему товару?

И по поводу конструкции "В", кто-то может на пальцах объяснить как она работает?

ЗЫ "Може я тупий?" (с) ТНМК
World1С
Конструкция запроса "В" - В (Значение), где значение - > тип: Список значений, Результат запроса, Массив.
Vofka
Цитата
Конструкция запроса "В" - В (Значение), где значение - > тип: Список значений, Результат запроса, Массив.


Т.е. если, например, Номенклатура В &СписокНоменклатуры, где СписокНоменклатуры = массв[товар1, товар2, товар3], то Номенклатура = массв[товар1, товар2, товар3] ?
World1С
Пример
ВЫБРАТЬ
   Спр.Номенклатура КАК Товар
ИЗ
   Справочник.Номенклатура КАК Спр
ГДЕ
   Спр.Номенклатура В (&СписокЗначений)

Запрос.УстановитьПараметр("СписокЗначений", СписокЗначений)


Где СписокЗначений -> Товар1, Товар2, ....... Товар n

Результат такого запроса будет

Товар1 шт.
Товар2 шт.
........
Товар n шт.

За Массив точно не помню но помоему работает
Vofka
А так запрос работать не будет:?



ВЫБРАТЬ
Спр.Номенклатура КАК Товар
ИЗ
Справочник.Номенклатура КАК Спр
ГДЕ
Спр.Номенклатура = &СписокЗначений

Запрос.УстановитьПараметр("СписокЗначений", СписокЗначений)
World1С
Почему, будет работать если элемент списка будет иметь тип СправочникСсылка.Номенклатура
Vofka
Цитата
Почему, будет работать если элемент списка будет иметь тип СправочникСсылка.Номенклатура


и если в списке значений будет только 1 элемент?

Если мы знаем, что СписокЗначений -> Товар1, Товар2, то можно

ВЫБРАТЬ
   Спр.Номенклатура КАК Товар
ИЗ
   Справочник.Номенклатура КАК Спр
ГДЕ
   Спр.Номенклатура В (&СписокЗначений)

Запрос.УстановитьПараметр("СписокЗначений", СписокЗначений)


заменить на

ВЫБРАТЬ
   Спр.Номенклатура КАК Товар
ИЗ
   Справочник.Номенклатура КАК Спр
ГДЕ
   Спр.Номенклатура = товар1
   ИЛИ Спр.Номенклатура = товар2

Запрос.УстановитьПараметр("СписокЗначений", СписокЗначений)
World1С
Только не или а союз "И"
Vofka
Вроде немного разъяснилось... smile.gif Спасибо!

Но вопрос в посте №70 - ещё актуален smile.gif
World1С
Напомни... happy.gif
Vofka
Елки-палки, на 9 постов выше этого
Цитата
ВОМБАТ, с добавлением к регистру партии нового измерения - я получил результат запроса какой хотел...
Vofka
Вроде получилось, посмотрите smile.gif необходимо зарегистрироваться для просмотра ссылки
вомбат
Цитата(Vofka @ 02.09.09, 11:44) необходимо зарегистрироваться для просмотра ссылки
Но теперь я не знаю как мне его использовать sad.gif . Как знать, что в выборке я перешёл к следующему товару?

Попробуй сам на него ответить. Свои рассужления начни с "а зачем мне это нужно?"... :-)
Vofka
ВОМБАТ, если не влом, посмотри как я сделал (ссылка выше на 2 поста), правильно или нет?
World1С
Будет свободная минутка, Я посмотрю...
Vofka
Жду smile.gif
вомбат
Цитата(Vofka @ 03.09.09, 10:16) необходимо зарегистрироваться для просмотра ссылки
ВОМБАТ, если не влом, посмотри как я сделал (ссылка выше на 2 поста), правильно или нет?


Не влом. А почему должно быть влом?
По скриншоту видно, что у тебя на выходе есть результат запроса, который ты можешь обойти по группировкам, т.е. как в 7.7 Пока Запрос.Группировка(1) = 1 Цикл и так далее по нужному числу группировок. Соответственно ты перейдешь на новый товар, когда завершится итерация по группировке первого уровня.
Vofka
Цитата
А почему должно быть влом?


не знаю smile.gif

Цитата
как в 7.7 Пока Запрос.Группировка(1) = 1 Цикл и так далее




...
Запрос = Новый Запрос;

Запрос.Текст =

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


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

Выборка = Запрос.Выполнить().Выбрать();

Пока Запрос.Группировка(1) = 1 Цикл

Сообщить("");

КонецЦикла;
...


Выдает ошибку: Метод объекта не обнаружен (Группировка)
World1С
Так работать и не будет, нужно вот так:

    Выборка = Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
    
    Пока Запрос.Следующий() = 1 Цикл
         ........
        КонецЦикла


В 8.* такого нет "Запрос.Группировка(1)"

Но судя из Вашего текста запроса, то такая конструкция работать у вас тоже не будет...

               |ПО
               |    ОБЩИЕ,


Запрос должен иметь вот такую конструкцию для обхода по группировкам, иначе

    Выборка = Запрос.Выполнить().Выбрать();
    
    Пока Запрос.Следующий() = 1 Цикл
         ........
        КонецЦикла


Этого достаточно
World1С
Прошу прощения:
вот правильно
    Выборка = Запрос.Выполнить().Выбрать();
    
    Пока Запрос.Следующий() 1 Цикл
         ........
    КонецЦикла    Выборка = Запрос.Выполнить().Выбрать();
Vofka
Цитата(World1С @ 04.09.09, 10:53) необходимо зарегистрироваться для просмотра ссылки
Так работать и не будет, нужно вот так:

    Выборка = Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
    
    Пока Запрос.Следующий() = 1 Цикл
         ........
        КонецЦикла


В 8.* такого нет "Запрос.Группировка(1)"

Но судя из Вашего текста запроса, то такая конструкция работать у вас тоже не будет...

               |ПО
               |    ОБЩИЕ,


Запрос должен иметь вот такую конструкцию для обхода по группировкам, иначе

    Выборка = Запрос.Выполнить().Выбрать();
    
    Пока Запрос.Следующий() = 1 Цикл
         ........
        КонецЦикла
                Выборка = Запрос.Выполнить().Выбрать();


Этого достаточно


Честно говоря мало, что понял... Т.е. в моем запросе сделать обход по группировкам нельзя? Что надо для того, чтоб можно юыло (как построить запрос)?

ЗЫ. Кто-то смотрел мою конфигурацию, я правильно сделал?
World1С
По группировкам обход выполнить возможно, если в твой запрос добавить группировки, пока не по чем делать обход
Vofka
У меня во вложенном запросе есть группировки



СГРУППИРОВАТЬ ПО
|РасходнаяНакладнаяРасход.Номенклатура,
|РасходнаяНакладная.Склад) КАК ВложенныйЗапрос


Или это не то?
World1С
Это не то, после обеда
Vofka
Цитата
Это не то, после обеда


Просто такая засада, что результат запроса есть, и вроде правильный, а как по нему списать - хз. Не могу списать правильно по ФИФО и хоть ты тресни 49000000.gif

Вот, например:


Как списать (напишите код)? 47047450.gif
вомбат
Я же выложил полностью рабочую процедуру проведения.
Нужно просто скопировать и вставить в модуль документа.
Vofka
Цитата
Я же выложил полностью рабочую процедуру проведения.
Нужно просто скопировать и вставить в модуль документа.


Спасибо! Разбераюсь теперь как он оработает... Получается у меня изначально запрос был не правильно построен...
вомбат
Цитата(Vofka @ 04.09.09, 16:04) необходимо зарегистрироваться для просмотра ссылки
Спасибо! Разбераюсь теперь как он оработает... Получается у меня изначально запрос был не правильно построен...


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