Имя: Пароль:
1C
1С v8
Выбор номенклатуры с положительным остатком
,
0 artprog
 
18.11.11
18:53
Подскажите пожалуйста, в чем ошибка:


dynamic zapros_nom = baza.NewObject("Запрос");
           zapros_nom.Текст = @"|ВЫБРАТЬ
|    ВложенныйЗапрос.Ссылка,
|    ВложенныйЗапрос.Остаток
|ИЗ
|    (ВЫБРАТЬ
|        СпрНоменклатура.Ссылка КАК Ссылка,
|        ВЫБОР
|            КОГДА ЕСТЬNULL(ТоварыНаСкладахОстатки.КоличествоОстаток, 0) - ЕСТЬNULL(ТоварыВРезервеНаСкладахОстатки.КоличествоОстаток, 0) <= 0
|                ТОГДА 0
|            ИНАЧЕ ЕСТЬNULL(ТоварыНаСкладахОстатки.КоличествоОстаток, 0) - ЕСТЬNULL(ТоварыВРезервеНаСкладахОстатки.КоличествоОстаток, 0)
|        КОНЕЦ КАК Остаток
|    ИЗ
|        Справочник.Номенклатура КАК СпрНоменклатура
|            ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыВРезервеНаСкладах.Остатки(, Склад = &Склад) КАК ТоварыВРезервеНаСкладахОстатки
|            ПО СпрНоменклатура.Ссылка = ТоварыВРезервеНаСкладахОстатки.Номенклатура
|            ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(, Склад = &Склад) КАК ТоварыНаСкладахОстатки
|            ПО СпрНоменклатура.Ссылка = ТоварыНаСкладахОстатки.Номенклатура
|    ГДЕ
|        СпрНоменклатура.ЭтоГруппа = ЛОЖЬ) КАК ВложенныйЗапрос
|ГДЕ
|    ВложенныйЗапрос.Остаток > 0";
           zapros_nom.УстановитьПараметр("Склад", baza.Справочники.Склады.НайтиПоКоду("000000001"));
           dynamic result = zapros_nom.Выполнить().Выбрать();
1 Ахиллес
 
18.11.11
18:59
Отрицательный остаток по ТоварыНаСкладахОстатки?
2 Ахиллес
 
18.11.11
19:02
Зачем тебе вообще нужен справочник номенклатуры если тебе только положительные остатки нужны?
3 artprog
 
18.11.11
19:07
null возвращается.

А что мне нужно?  Ахиллес, я не 1сник :) Есть какой-то регистр накопления ТоварыНаСкладах вроде?:)
Как проще выбрать по заданному складу остатки >0 ?
4 Конфигуратор1с
 
18.11.11
19:11
(3) делаете запрос к виртуальной таблице остатки регистра ТоварыНаСкладах  и выбираете все с конечным остатком
5 shuhard
 
18.11.11
19:12
(4)[и выбираете все с конечным остатком]
а есть бесконечный ?
Оооооооооооооо
6 Конфигуратор1с
 
18.11.11
19:22
+(4)|    ТоварыНаСкладахОстатки.Номенклатура
 |ИЗ
 |    РегистрНакопления.ТоварыНаСкладах.Остатки(&Дата1, ) КАК ТоварыНаСкладахОстатки"
7 Конфигуратор1с
 
18.11.11
19:22
(5) я спутал название поля с таблицы остатки и обороты. Пятница))
8 artprog
 
18.11.11
19:46
Как-то так получилось..

ВЫБРАТЬ
   ТоварыНаСкладах.Склад,
   ТоварыНаСкладах.Номенклатура,
   СУММА(ТоварыНаСкладах.Количество) КАК Количество,
ИЗ
   РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах
ГДЕ
   ТоварыНаСкладах.Склад = &Склад
9 artprog
 
18.11.11
19:49
нет, не то я сделал. мне ведь нужна номенклатура в наличии, а это вообще хз что))
10 Конфигуратор1с
 
18.11.11
20:18
(9) ну так правильно все сделал, единственное, нафига тебе выводить склад?
11 Конфигуратор1с
 
18.11.11
20:19
+нужно брать не реальную таблицу,а виртуальную
12 Конфигуратор1с
 
18.11.11
20:20
ВЫБРАТЬ

   ТоварыНаСкладах.Номенклатура,
   СУММА(ТоварыНаСкладах.КоличествоОстаток) КАК Остаток,
ИЗ
   РегистрНакопления.ТоварыНаСкладах.Остатки(&Дата1, ) КАК ТоварыНаСкладах
ГДЕ
   ТоварыНаСкладах.Склад = &Склад
13 artprog
 
18.11.11
20:25
(12) в регистре накопления находится вся номенклатура, или не равная 0?
14 Конфигуратор1с
 
18.11.11
20:29
(13) регистр накопления это физическая таблица. К ней платформа формирует для скорости работы виртуальные таблицы, в зависимости от вида регистра накопления это таблица остатки, обороты, и остатки и обороты. В таблице остатки хранятся только номенклатура с остатком на указанную дату. Если дату не указать, то он выберет последние остатки
15 Конфигуратор1с
 
18.11.11
20:30
(13) создайте запрос конструктором и Вы увидите все таблицы для этого регистра.
16 aleks-id
 
18.11.11
20:33
(13) представь регистр накопления, как котел, в котором варятся "бульки". на какой то момент времени они будут одни, на другой - другие. это похоже на OLAP-кубы.
17 artprog
 
18.11.11
20:35
при выполнении запроса из (12) возникает null exception, т.е. ничего не возвращается..

           dynamic zapros_nom = baza.NewObject("Запрос");
           zapros_nom.Текст = @"ВЫБРАТЬ
                        ТоварыНаСкладах.Номенклатура,
                   СУММА(ТоварыНаСкладах.КоличествоОстаток) КАК Остаток,
               ИЗ
                   РегистрНакопления.ТоварыНаСкладах.Остатки(, ) КАК ТоварыНаСкладах
               ГДЕ
                   ТоварыНаСкладах.Склад = &Склад";
           zapros_nom.УстановитьПараметр("Склад", baza.Справочники.Склады.НайтиПоКоду("000000001"));
           dynamic result = zapros_nom.Выполнить().Выбрать();
18 artprog
 
18.11.11
20:36
aleks-id, Конфигуратор1с - спасибо, что поясняете :) начинаю входить в курс дела потихоньку))
19 Конфигуратор1с
 
18.11.11
20:37
(17) так а Вы в 1ске сначала сделайте запрос и поглядите чего там есть на остатке по данному складу.
20 Конфигуратор1с
 
18.11.11
20:37
если конфа типовая то там есть консоль отчетов
21 artprog
 
18.11.11
20:40
(19) товара на этом складе более чем достаточно))
22 aleks-id
 
18.11.11
20:44
а если сделать так:
           dynamic zapros_nom = baza.NewObject("Запрос");
           zapros_nom.Текст = @"ВЫБРАТЬ
                        ОстаткиТоваров.Номенклатура КАК Tovar,
                        ОстаткиТоваров.КоличествоОстаток КАК Kolichestvo
               ИЗ
                   РегистрНакопления.ТоварыНаСкладах.Остатки(&Дата, ) КАК ОстаткиТоваров";
           zapros_nom.УстановитьПараметр("Дата", baza.ТекущаяДата());
           dynamic result = zapros_nom.Выполнить().Выгрузить();
23 artprog
 
18.11.11
20:44
Вот эти запросы работают без проблем:

ВЫБРАТЬ
           рег_номенклатуры.Номенклатура,
           рег_номенклатуры.Статус
          ИЗ
           РегистрСведений.рег_номенклатуры КАК рег_номенклатуры



ВЫБРАТЬ
                        ЦеныНоменклатурыСрезПоследних.Цена
                       ИЗ
                        РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, Номенклатура = &Ном И ТипЦен = &ТипЦены)
                       КАК ЦеныНоменклатурыСрезПоследних



ВЫБРАТЬ
                        ОстаткиНаСкладе.КоличествоОстаток КАК Остаток
                       ИЗ
                        РегистрНакопления.ТоварыНаСкладах.Остатки(, Номенклатура = &Ном И Склад = &Склад)
                       КАК ОстаткиНаСкладе
24 artprog
 
18.11.11
20:47
(22) ругается на baza.ТекущаяДата(), говорит не содержит метода ТекущаяДата()
25 aleks-id
 
18.11.11
20:50
(24) блин. ТекущаяДата это функция среза момента времени на "прям щас". я не помню как через КОМ ее вызвать :)
26 artprog
 
18.11.11
20:52
а вручную ее можно задать, например "19112011"?
27 artprog
 
18.11.11
20:55
(25) Выбрал номенклатуру! Убрал дату вообще.

но выбрал по всем складам видимо, а чтобы присутствующую на конкретном складе - что дописать нужно?
28 Конфигуратор1с
 
18.11.11
20:56
ГДЕ
                   ТоварыНаСкладах.Склад = &Склад";
           zapros_nom.УстановитьПараметр("Склад", baza.Справочники.Склады.НайтиПоКоду("000000001"));
29 Конфигуратор1с
 
18.11.11
20:57
"Склад", baza.Справочники.Склады.НайтиПоКоду("000000001") - тебе возвращает ком объект а не ссылку
30 Конфигуратор1с
 
18.11.11
20:57
поэтому и нулл
31 artprog
 
18.11.11
20:58
result.Tovar - это будет ссылка на номенклатуру?
а result.Kolichestvo - остаток?
32 aleks-id
 
18.11.11
20:58
(28) да похоже тут у него затык
(27) попробуй dynamic sklad = baza.Справочники.Склады.НайтиПоКоду("000000001"));
в sklad будет чтонить?
33 Конфигуратор1с
 
18.11.11
20:59
ТоварыНаСкладах.Склад в (Выбрать ссылка из справочники.Склады где Код = "00000000001" ) - както так
34 Конфигуратор1с
 
18.11.11
21:00
(32) у меня такая байда была при сом соединении двух 8шных баз
35 aleks-id
 
18.11.11
21:03
(31) в result у тебя будет ком-объект в виде набора ком-объектов. тавтология конечно, но это безобразие надо обходить в цикле.
тогда for each stroka_result from result
в stroka_result.Tovar получишь Номенклатуру (ком)
в stroka_result.Kolichestvo получишь количество (строка или число)
36 Конфигуратор1с
 
18.11.11
21:04
ВЫБРАТЬ
   ТоварыНаСкладахОстатки.Номенклатура,
   СУММА(ТоварыНаСкладахОстатки.КоличествоОстаток) КАК КоличествоОстаток
ИЗ
   РегистрНакопления.ТоварыНаСкладах.Остатки КАК ТоварыНаСкладахОстатки
ГДЕ
   ТоварыНаСкладахОстатки.Склад В
           (ВЫБРАТЬ
               склад.Ссылка
           ИЗ
               справочник.склады КАК склад
           ГДЕ
               склад.Код = "000000001")

СГРУППИРОВАТЬ ПО
   ТоварыНаСкладахОстатки.Номенклатура
37 Конфигуратор1с
 
18.11.11
21:04
(35) так может ему номенклатура наименование взять вместо ссылки?
38 aleks-id
 
18.11.11
21:05
(37) ну это уже ему решать. только надо сначала понять почему склад не пашет
39 Конфигуратор1с
 
18.11.11
21:08
(38) так потому и не пашет, что в параметр он передает ком объект вместо ссылки
40 aleks-id
 
18.11.11
21:11
(39) это для передающей стороны он ком. для принимающей - её родной.
41 aleks-id
 
18.11.11
21:12
и вообще можно тогда написать
ГДЕ
   ТоварыНаСкладахОстатки.Склад.Код = "000000001"
42 artprog
 
18.11.11
21:19
baza.Справочники.Склады.НайтиПоКоду("000000001")

дает значение system com object
Пробовал дописать .REF, без изменений.


   ТоварыНаСкладахОстатки.Склад.Код = "000000001"

также не прошло
43 artprog
 
18.11.11
21:25
чудеса в решете.. запрос из (36) тоже не проходит!
44 Конфигуратор1с
 
18.11.11
21:33
код покажи
45 aleks-id
 
18.11.11
21:33
так. последняя попытка
 dynamic zapros_nom = baza.NewObject("Запрос");
 zapros_nom.Текст = @"ВЫБРАТЬ
         ОстаткиТоваров.Номенклатура КАК Tovar,
         ОстаткиТоваров.КоличествоОстаток КАК Kolichestvo
      ИЗ
         РегистрНакопления.ТоварыНаСкладах.Остатки(, ) КАК ОстаткиТоваров
      ГДЕ
         ОстаткиТоваров.Склад.Код = ""000000001""";
 dynamic result = zapros_nom.Выполнить().Выгрузить();

+ поиграй с количеством кавычек в ОстаткиТоваров.Склад.Код = ""000000001""" если не сработает
46 artprog
 
18.11.11
21:43
(45) удалось :) Огромнейшее спасибо :)

А как обработать исключение, допустим не установлена цена на какую-то номенклатурную позицию.
Можно в запросе

"ВЫБРАТЬ
                        ЦеныНоменклатурыСрезПоследних.Цена
                       ИЗ
                        РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, Номенклатура = &Ном И ТипЦен = &ТипЦены)
                       КАК ЦеныНоменклатурыСрезПоследних"

указать, что если значения нет - вернуть 0 например?
47 artprog
 
18.11.11
21:44
а я писал так: /""000000001"/"";
48 artprog
 
18.11.11
21:46
Кстати, очень интересно, что в данном запросе ТипЦены задается также, как мы задавали ТипСклада. И он работает.

dynamic zapros_cena = baza.NewObject("Запрос");
                       zapros_cena.Текст =
                     @"ВЫБРАТЬ
                        ЦеныНоменклатурыСрезПоследних.Цена
                       ИЗ
                        РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, Номенклатура = &Ном И ТипЦен = &ТипЦены)
                       КАК ЦеныНоменклатурыСрезПоследних";
                       zapros_cena.УстановитьПараметр("Ном", nomenk);
                       zapros_cena.УстановитьПараметр("ТипЦены", baza.Справочники.ТипыЦенНоменклатуры.НайтиПоКоду("000000016"));
49 aleks-id
 
18.11.11
21:49
(46) ГДЕ НЕ ЦеныНоменклатурыСрезПоследних.Цена ЕСТЬ NULL
50 artprog
 
18.11.11
22:02
(49) не помогло.. около тысячи номенклатуры прогоняет нормально, а потом на какую-то косячную позицию натыкается и пишет  - ошибка при вызове "result_cena.Цена"

Есть над чем работать)
51 artprog
 
18.11.11
22:06
(35) а я вместо Выгрузить пишу Выбрать. Это сильно влияет на производительность.
С Выбрать удобно перебирается:

while ((bool)result.Следующий()) {}

а вот как перебрать com объект из объектов я не догоняю.. )
Выдавать глобальные идеи — это удовольствие; искать сволочные маленькие ошибки — вот настоящая работа. Фредерик Брукс-младший