Вход | Регистрация

  1  2   
1С:Предприятие :: 1С:Предприятие 7.7 и ранее

v7: 1С++

v7: 1С++
Я
   bananan
 
28.12.12 - 18:35
Добрый вечер, может еще кто есть?
Значит так... Решил я "набить" руку по Запросам под 1С++. Взял отчет ОстаткиТМЦ из конфигураци, хочу "заточить" его под 1с++..
понятно пока только пробую. Т.е. то, что ейчас в тексте запроса не совсем то, что будет в результате этой работы...
ТАк вот текст запроса у меня такой:
ТекстЗапроса = "
                    |select         
                    | Регистр.Остатки.Фирма AS [Фирма $Справочник.Фирмы]
                    | Регистр.Остатки.Кво AS   [Кво $Регистр.Остатки.Кво]
                    | FROM $Регистр.Остатки as Рег                
                    | WHERE $Регистр.Остатки.Кво<10";
Так ругается:
Incorrect syntax near 'Регистр'.
В чем у меня ошибка?
 
 
   DEVIce
 
1 - 28.12.12 - 18:39
В селект-листе наверной надо писать назначенный алиас, как ты думаешь?
Select
Рег.Фирма
....
И так далее. Ты в запросах-то вообще шаришь?
   DEVIce
 
2 - 28.12.12 - 18:40
А так вообще не вижу смысла НАЧИНАТЬ ковырять 1С++. Его надо уже заканчивать ковырять и заниматьчя v8.
   GLazNik
 
3 - 28.12.12 - 18:41
+(1) Или $Регистр.Остатки.Фирма
   КонецЦикла
 
4 - 28.12.12 - 18:42
$Рег.Количество AS   Кво
   Mikeware
 
5 - 28.12.12 - 18:42
(2) знание сиквельных запросов очень помогает при переходе на снеговика.
а если еще пользуешься не "чистым" 1с++, а классом ПоставшикДанных - еще более...
   DEVIce
 
6 - 28.12.12 - 18:44
(5) Это да, согласен. Самому здорово помогло. Если по работе приходилось ковырять 1С++ и прямые запросы, то без вопросов. Но НАЧИНАТЬ ковырять 1С++, чтобы было проще освоить v8 - а нафига?
   Sereja
 
7 - 28.12.12 - 18:48
(0) Скачай конструктор запросов для 1cpp и тебе станет легче
   КонецЦикла
 
8 - 28.12.12 - 18:51
(6) А кто тебе сказал, что автор собирается осваивать и что это ему нужно/пригодиццо :)
   Андрей_Андреич
 
9 - 28.12.12 - 18:52
(6) Человеку кушать хочется. За что платят - на том и работаем.
   bananan
 
10 - 28.12.12 - 19:00
(7) Не в курсе где его можно скачать?
 
 Рекламное место пустует
   bananan
 
11 - 28.12.12 - 19:21
У меня конфигурация для Украины.
Регистр.Остатки.Кво - это количество остатков. Но, выдает:
Текст Запроса такой:
   
    ТекстЗапроса = "
                    |select         
                    | $Регистр.Остатки.Фирма AS [Фирма $Справочник.Фирмы]
                    | $Регистр.Остатки.Кво AS Кво
                    | FROM $Регистр.Остатки as Рег                
 
                   | WHERE $Регистр.Остатки.Кво<10";
Incorrect syntax near 'sp1055'.
   Дык ё
 
12 - 28.12.12 - 19:24
(11) будь мужиком, поставь запятую :-)
   bananan
 
13 - 28.12.12 - 19:25
(12) :) Спасибо!
   Mikeware
 
14 - 28.12.12 - 19:26
(12) тут не запятую надо ставить, а читать документацию....
   EvgeniuXP
 
15 - 28.12.12 - 19:27
(14) в документации написано: поставьте запятую :)
   monsterZE
 
16 - 28.12.12 - 22:46
(0) я тебе на мыло скинул доку.. там черным по русскому. =) и про регистры в том числе.
   bezgudroman
 
17 - 28.12.12 - 22:50
Да, маны курить ему прийдется..
   Злопчинский
 
18 - 28.12.12 - 22:54
В документации ненаписано достаточно много.. документация - она как паззл... от 3 до 5
   bananan
 
19 - 29.12.12 - 11:48
Доброе утро!
Написал такой код:
ТекстЗапроса = "
                    |select         
                    | $Регистр.Остатки.Фирма AS [Фирма $Справочник.Фирмы]
                    | ,$Регистр.Остатки.ТМЦ AS [ТМЦ $Справочник.ТМЦ]
                    | ,$Регистр.Остатки.Кво AS Кво";

    Если Режим = "Подробно" Тогда
        ТекстЗапр = ТекстЗапр+"
                    | ,$Регистр.Остатки.Партия";
    КонецЕсли;           
    
    ТекстЗапроса = ТекстЗапроса + "
                    | ,$Регистр.Остатки.СуммаГрн AS СуммаГрн
                    | ,$Регистр.Остатки.СуммаБезНДС AS СуммаБезНДС
                    | ,$Регистр.Остатки.СуммаОсн AS СуммаОсн
                    | ,$Регистр.Остатки.Наценка AS Наценка";
    Если (сВидУчета.ПолучитьЗначение(сВидУчета.ТекущаяСтрока())="Бухгалтерия") Тогда
        ТекстЗапр = ТекстЗапр+"
        | WHERE $Регистр.Остатки.Фирма IN (SELECT VAL FROM #Группа)";
 
        Заг = Заг+"По бухгалтерским данным. По фирме "+выбФирма+". ";

Запр=СоздатьОбъект("ODBCRecordset");
    ТЗ = Запр.ВыполнитьИнструкцию(ТекстЗапроса);
    Запр.УложитьСписокОбъектов(выбФирма, "#Группа","Фирма");
 
Выдает:
Запр.УложитьСписокОбъектов(выбФирма, "#Группа","Фирма");;                        
 
{\\SERVER12\VPKTEST$\EXTFORMS\ЗАЛИШКИ ТМЦ.ERT(88)}: Недопустимое значение третьего аргумента метода!
Фирма у меня есть в селекте... Что здесь не так?
   Mikeware
 
20 - 29.12.12 - 11:49
(19) ДНК
   vinogradъ
 
21 - 29.12.12 - 12:01
(19) забей, пиши ещё
   bananan
 
22 - 29.12.12 - 12:06
(20)(21) Так в чем ошибка?
   sapphire
 
23 - 29.12.12 - 12:06
УложитьСписокОбъектов(<?>,<?>,<?>)
Синтаксис:
PutObjectList(ObjList, strTableName, strRefKinde)
Назначение:
сохраняет список объектов во временной таблице MS SQL. Идентификаторы
объектов из списка ObjList сохраняются во временной таблице strTableName. Таблица 
имеет единственное поле val char(9). Имя таблицы должно начинаться с символа «#». 
 
Если strRefKinde идентификатор иерархического справочника, то таблица будет
содержать элементы иерархически принадлежащие группам переданным в списке.
(Подобно оператору «в» стандартного языка запросов 1С.)
Параметры:
- ObjList (СписокЗначений/АгрегатныйТип): список для сохранения или 
элемент справочника, группа справочника, документ и т.п.;
- strTableName (строка): имя таблицы;
- strRefKinde (строка): вид справочника для иерархического включения элементов или вид плана счетов для иерархического включения счетов;
   sapphire
 
24 - 29.12.12 - 12:07
Запр.УложитьСписокОбъектов(выбФирма, "#Группа","Фирмы");
   sapphire
 
25 - 29.12.12 - 12:07
- strRefKinde (строка): вид справочника для иерархического включения элементов или вид плана счетов для иерархического включения счетов;
   sapphire
 
26 - 29.12.12 - 12:09
Запр=СоздатьОбъект("ODBCRecordset");
    Запр.УложитьСписокОбъектов(выбФирма, "#Группа","Фирмы");// Было "Фирма", а нужен вид справочника, значит "Фирмы"
 
    ТЗ = Запр.ВыполнитьИнструкцию(ТекстЗапроса);
   bananan
 
27 - 29.12.12 - 12:11
(23)-(26) Спасибо
   bananan
 
28 - 29.12.12 - 12:55
Теперь такая фигня:
Нужно сделать WHERE по выбраному складу...
Написал так:
ТекстЗапр = ТекстЗапр+"
        | WHERE $Регистр.Остатки.Склад IN (SELECT VAL FROM #Группа)";    
 
. . .
Запр.УложитьСписокОбъектов(выбСклад, "#Группа","Склады");
 
Выдает:
State 42S22, native 207, message [Microsoft][ODBC SQL Server Driver][SQL Server]Invalid column name 'sp1855'
   bananan
 
29 - 29.12.12 - 13:00
+(28) Запрашиваем у Справочника Склады, вроде все так, а не так ведь
   bananan
 
30 - 29.12.12 - 13:11
Почему столбец инвалидный?!
   sapphire
 
31 - 29.12.12 - 13:11
try
   Запр.УложитьСписокОбъектов(выбСклад, "#Группа","Склады");
 
except
   Message(ОписаниеОшибки());
   Meta=CreateObject("MetaDataWork");
   Message("===== Запрос в t-SQL ======");
   Message(Meta.ОбрМетаСКЛ(ТекстЗапр));
   Message("===========++++++++++++++++");
endtry;
   bananan
 
32 - 29.12.12 - 13:16
(31) Все равно выдает6
State 42S22, native 207, message [Microsoft][ODBC SQL Server Driver][SQL Server]Invalid column name 'sp1855'.
и ничего больше може я try не там вызываю?
полный код с\после описания текста запроса у меныя такой:
    Запр=СоздатьОбъект("ODBCRecordset");
    Запр.Отладка(1);
    ТЗ = Запр.ВыполнитьИнструкцию(ТекстЗапроса);
    Запр.УложитьСписокОбъектов(выбФирма, "#Группа","Фирмы");
 
    try
           Запр.УложитьСписокОбъектов(выбСклад, "#Группа","Склады");
 
    except
           Message(ОписаниеОшибки());
           Meta=CreateObject("MetaDataWork");
           Message("===== Запрос в t-SQL ======");
           Message(Meta.ОбрМетаСКЛ(ТекстЗапр));
           Message("===========++++++++++++++++");
    endtry;
    ТЗ.ВыбратьСтроку();
   Sereja
 
33 - 29.12.12 - 13:18
 
 
   sapphire
 
34 - 29.12.12 - 13:20
Запр=СоздатьОбъект("ODBCRecordset");
    Запр.Отладка(1);


 
    try
           Запр.УложитьСписокОбъектов(выбСклад, "#Группа","Склады");
 
          ТЗ = Запр.ВыполнитьИнструкцию(ТекстЗапроса);
          ТЗ.ВыбратьСтроку();   
    except
           Message(ОписаниеОшибки());
           Meta=CreateObject("MetaDataWork");
           Message("===== Запрос в t-SQL ======");
           Message(Meta.ОбрМетаСКЛ(ТекстЗапр));
           Message("===========++++++++++++++++");
    endtry;
   sapphire
 
35 - 29.12.12 - 13:22
(33) Нуна все эти конструкторы... В 1С особенно.
Писари 1С этими конструкторами только галиматью писать умеют
   bananan
 
36 - 29.12.12 - 13:23
(34) Не понял...
(35) и никакого конструктора я не применяя - пишу сам
   Sereja
 
37 - 29.12.12 - 13:23
(35) Так не используй. Я ж не тебе ссылку даю.
   bananan
 
38 - 29.12.12 - 13:34
(34) понял.
Выдает:
Дата конца отчета установлена после границы последовательности документов (28.12.03 12:00:00)
Данные отчета могут быть неактульными!

select        
 sp1855 AS [Фирма $Справочник.Фирмы]
 ,sp1053 AS [ТМЦ $Справочник.ТМЦ]
 ,sp1055 AS Кво
 ,sp1056 AS СуммаГрн
 ,sp1057 AS СуммаБезНДС
 ,sp1058 AS СуммаОсн
 ,sp1059 AS Наценка
WHERE sp1055<10
State 42S22, native 207, message [Microsoft][ODBC SQL Server Driver][SQL Server]Invalid column name 'sp1855'.
===== Запрос в t-SQL ======

select         
 sp1855 AS [Фирма $Справочник.Фирмы]
 ,sp1053 AS [ТМЦ $Справочник.ТМЦ]
 ,sp1055 AS Кво
 ,sp1056 AS СуммаГрн
 ,sp1057 AS СуммаБезНДС
 ,sp1058 AS СуммаОсн
 ,sp1059 AS Наценка
 WHERE sp1055<10
===========++++++++++++++++
   bananan
 
39 - 29.12.12 - 13:35
Перед тем как добавил на проверку склада. Фира - его устраивал - не ругался, а теперь ругается
   bananan
 
40 - 29.12.12 - 13:50
Помогите!
   bananan
 
41 - 29.12.12 - 14:02
(+39) А заремарил выбФирма
выдает:
select        
 sp1855 AS [Фирма $Справочник.Фирмы]
 ,sp1053 AS [ТМЦ $Справочник.ТМЦ]
 ,sp1055 AS Кво
 ,sp1056 AS СуммаГрн
 ,sp1057 AS СуммаБезНДС
 ,sp1058 AS СуммаОсн
 ,sp1059 AS Наценка
WHERE sp1055<10
State 42S22, native 207, message [Microsoft][ODBC SQL Server Driver][SQL Server]Invalid column name 'sp1855'.
===== Запрос в t-SQL ======

select         
 sp1855 AS [Фирма $Справочник.Фирмы]
 ,sp1053 AS [ТМЦ $Справочник.ТМЦ]
 ,sp1055 AS Кво
 ,sp1056 AS СуммаГрн
 ,sp1057 AS СуммаБезНДС
 ,sp1058 AS СуммаОсн
 ,sp1059 AS Наценка
 WHERE sp1055<10
===========++++++++++++++++
   bananan
 
42 - 29.12.12 - 14:18
Здесь есть кто-нибудь живой???
   bananan
 
43 - 29.12.12 - 14:31
Оставил в коде :
    ТекстЗапроса = "
                    |select         
                    | $Регистр.Остатки.Фирма AS [Фирма $Справочник.Фирмы]
                    | ,$Регистр.Остатки.ТМЦ AS [ТМЦ $Справочник.ТМЦ]
                    | ,$Регистр.Остатки.Кво AS Кво";

    Если Режим = "Подробно" Тогда
        ТекстЗапр = ТекстЗапр+"
                    | ,$Регистр.Остатки.Партия";
    КонецЕсли;           
    
    ТекстЗапроса = ТекстЗапроса + "
                    | ,$Регистр.Остатки.СуммаГрн AS СуммаГрн
                    | ,$Регистр.Остатки.СуммаБезНДС AS СуммаБезНДС
                    | ,$Регистр.Остатки.СуммаОсн AS СуммаОсн
                    | ,$Регистр.Остатки.Наценка AS Наценка";
    Если (сВидУчета.ПолучитьЗначение(сВидУчета.ТекущаяСтрока())="Бухгалтерия") Тогда
        ТекстЗапр = ТекстЗапр+"
            | WHERE $Регистр.Остатки.Фирма IN (SELECT VAL FROM #Группа)";
 
        Заг = Заг+"По бухгалтерским данным. По фирме "+выбФирма+". ";
    Иначе                      
        ТекстЗапр = ТекстЗапр+"
            | ,$Регистр.Остатки.Фирма NOT IN (SELECT VAL FROM #Группа)";
 
        Заг = Заг+"По торговым данным. ";
    КонецЕсли;                       

   //ТекстЗапр = ТекстЗапр+"
 
   //|Условие (Скл в выбСклад);
 
      //|Условие (ТМЦ в выбТМЦ);
 
   //|Группировка Скл;
 
   //|Группировка ТМЦ;";
 
   //Если Режим = "Подробно" Тогда
 
   //    ТекстЗапр = ТекстЗапр+"               
 
   //    |Группировка Пар;";
 
   //КонецЕсли;
 
   //ТекстЗапр = ТекстЗапр+"
 
   //|Функция ККво = КонОст(Кво);
 
   //|Функция КСуммаГрн = КонОст(СуммаГрн);
 
   //|Функция КСуммаБезНДС = КонОст(СуммаБезНДС);
 
   //|Функция КСуммаОсн = КонОст(СуммаОсн);
 
   //|Функция КНаценка = КонОст(Наценка);";
 
    
    
    Запр=СоздатьОбъект("ODBCRecordset");
    Запр.Отладка(1);
    ТЗ = Запр.ВыполнитьИнструкцию(ТекстЗапроса);
    Запр.УложитьСписокОбъектов(выбФирма, "#Группа","Фирмы");
 
    ТЗ.ВыбратьСтроку();
   bananan
 
44 - 29.12.12 - 14:31
Все равно віждает все ту же ошибку ODBC SQL Server Driver][SQL Server]Invalid column name 'sp1855
   bananan
 
45 - 29.12.12 - 14:32
Ща буду писать по-новой, блин
   kiruha
 
46 - 29.12.12 - 14:34
FROM
   kiruha
 
47 - 29.12.12 - 14:35
Где ???
   kiruha
 
48 - 29.12.12 - 14:36
Б-ть
   bananan
 
49 - 29.12.12 - 14:39
(45)-(48) Не понял
 
 Рекламное место пустует
   kiruha
 
50 - 29.12.12 - 14:45
Отсутствует секция FROM
элементарный учебник
http://www.sql-tutorial.ru/ru/book_select_statement.html
   bananan
 
51 - 29.12.12 - 14:45
+(49) понял, вставил я FROM и...
Server]Incorrect syntax near the keyword 'FROM'.
полный код:
ТекстЗапроса = "
                    |select         
                    | $Регистр.Остатки.Фирма AS [Фирма $Справочник.Фирмы]
                    | ,$Регистр.Остатки.ТМЦ AS [ТМЦ $Справочник.ТМЦ]
                    | ,$Регистр.Остатки.Кво AS Кво";

    Если Режим = "Подробно" Тогда
        ТекстЗапр = ТекстЗапр+"
                    | ,$Регистр.Остатки.Партия";
    КонецЕсли;           
    
    ТекстЗапроса = ТекстЗапроса + "
                    | ,$Регистр.Остатки.СуммаГрн AS СуммаГрн
                    | ,$Регистр.Остатки.СуммаБезНДС AS СуммаБезНДС
                    | ,$Регистр.Остатки.СуммаОсн AS СуммаОсн
                    | ,$Регистр.Остатки.Наценка AS Наценка";
    Если (сВидУчета.ПолучитьЗначение(сВидУчета.ТекущаяСтрока())="Бухгалтерия") Тогда
        ТекстЗапр = ТекстЗапр+"
            | WHERE $Регистр.Остатки.Фирма IN (SELECT VAL FROM #Группа)";
 
        Заг = Заг+"По бухгалтерским данным. По фирме "+выбФирма+". ";
    Иначе                      
        ТекстЗапр = ТекстЗапр+"
            | ,$Регистр.Остатки.Фирма NOT IN (SELECT VAL FROM #Группа)";
 
        Заг = Заг+"По торговым данным. ";
    КонецЕсли;                       

   //ТекстЗапр = ТекстЗапр+"
 
   //|Условие (Скл в выбСклад);
 
      //|Условие (ТМЦ в выбТМЦ);
 
   //|Группировка Скл;
 
   //|Группировка ТМЦ;";
 
   //Если Режим = "Подробно" Тогда
 
   //    ТекстЗапр = ТекстЗапр+"               
 
   //    |Группировка Пар;";
 
   //КонецЕсли;
 
   //ТекстЗапр = ТекстЗапр+"
 
   //|Функция ККво = КонОст(Кво);
 
   //|Функция КСуммаГрн = КонОст(СуммаГрн);
 
   //|Функция КСуммаБезНДС = КонОст(СуммаБезНДС);
 
   //|Функция КСуммаОсн = КонОст(СуммаОсн);
 
   //|Функция КНаценка = КонОст(Наценка);";
 
    ТекстЗапр = ТекстЗапр+"
        | WHERE $Регистр.Остатки.Склад IN (SELECT VAL FROM #Группа)";    
 
    ТекстЗапроса = ТекстЗапроса + "
        | WHERE $Регистр.Остатки.Кво<10";
    
ТекстЗапроса = ТекстЗапроса + "
        | FROM $Регистр.Остатки AS Рег";

    Запр=СоздатьОбъект("ODBCRecordset");
    Запр.Отладка(1);
 //    ТЗ = Запр.ВыполнитьИнструкцию(ТекстЗапроса);
 
    Запр.УложитьСписокОбъектов(выбФирма, "#Группа","Фирмы");
 
    try
           Запр.УложитьСписокОбъектов(выбСклад, "#Группа","Склады");
 
           ТЗ = Запр.ВыполнитьИнструкцию(ТекстЗапроса);
           ТЗ.ВыбратьСтроку();
    except
   ДенисЧ
 
52 - 29.12.12 - 14:47
ммммммммммммммммммммммаааааааааааааааааааааатььь....

Автор, ты бы хотя бы синтаксис скуля почитал... Примитивнейший... Какое слово за каким должно идти...
   bananan
 
53 - 29.12.12 - 14:50
(52) От блин, да знаю я синтаксис невнимательность просто... вот и перепутал местами Фром и Вера
   bananan
 
54 - 29.12.12 - 14:51
(52) А за подсказку спасибо
   kiruha
 
55 - 29.12.12 - 15:04
там у тебя еще куча ошибок
лучше почитать день SQL учебник - пригодится и для работы и для 8.2
1С++ это всего лишь надстройка над языком SQL
   bananan
 
56 - 29.12.12 - 15:20
(55) Почитаю на выходных, а если не трудно, то где там куча ошибок? И еще сейчас у меня что-то с AND не котачит
Выдает:
Incorrect syntax near the keyword 'AND'
В коде у меня так:
    Если (сВидУчета.ПолучитьЗначение(сВидУчета.ТекущаяСтрока())="Бухгалтерия") Тогда
        ТекстЗапр = ТекстЗапр+"
            | WHERE $Регистр.Остатки.Фирма IN (SELECT VAL FROM #Группа)";
 
        Заг = Заг+"По бухгалтерским данным. По фирме "+выбФирма+". ";
    Иначе                      
        ТекстЗапр = ТекстЗапр+"
            | WHERE $Регистр.Остатки.Фирма NOT IN (SELECT VAL FROM #Группа)";
 
        Заг = Заг+"По торговым данным. ";
    КонецЕсли;                      
    ТекстЗапр = ТекстЗапр+"
        | AND ($Регистр.Остатки.Склад IN (SELECT VAL FROM #Группа))";    
 
        
    ТекстЗапроса = ТекстЗапроса + "
        | AND ($Регистр.Остатки.Кво<10)";
   Стрелок
 
57 - 29.12.12 - 15:23
сдаётся мне это кто то из гуру тролит. уж совсем по-тупому
   bananan
 
58 - 29.12.12 - 15:25
(57) когда кажется - крестится надо. Я скорее начинающий (не смотря на не малое пребывание на этом форуме)
   bananan
 
59 - 29.12.12 - 15:26
подскажите что там с AND?
   Стрелок
 
60 - 29.12.12 - 15:28
(58) читайте документацию!!!!
   bananan
 
61 - 29.12.12 - 15:29
(60) Обширный и обстоятельный ответ
   Стрелок
 
62 - 29.12.12 - 15:29
это что

Заг = Заг+"По торговым данным. ";
    КонецЕсли;                      
    ТекстЗапр = ТекстЗапр+"
        | AND ($Регистр.Остатки.Склад IN (SELECT VAL FROM #Группа))";   
 

ты бл хоть отладку включал?
   bananan
 
63 - 29.12.12 - 15:31
Мин сча покажу весь код (почти весь):
ТекстЗапроса = ТекстЗапроса + "
        | FROM $Регистр.Остатки AS Рег";


   //ТекстЗапр = ТекстЗапр+"
 
      //|Условие (ТМЦ в выбТМЦ);
 
   //|Группировка Скл;
 
   //|Группировка ТМЦ;";
 
   //Если Режим = "Подробно" Тогда
 
   //    ТекстЗапр = ТекстЗапр+"               
 
   //    |Группировка Пар;";
 
   //КонецЕсли;
 
   //ТекстЗапр = ТекстЗапр+"
 
   //|Функция ККво = КонОст(Кво);
 
   //|Функция КСуммаГрн = КонОст(СуммаГрн);
 
   //|Функция КСуммаБезНДС = КонОст(СуммаБезНДС);
 
   //|Функция КСуммаОсн = КонОст(СуммаОсн);
 
   //|Функция КНаценка = КонОст(Наценка);";
 
       Если (сВидУчета.ПолучитьЗначение(сВидУчета.ТекущаяСтрока())="Бухгалтерия") Тогда
        ТекстЗапр = ТекстЗапр+"
            | WHERE ($Регистр.Остатки.Фирма IN (SELECT VAL FROM #Группа))";
 
        Заг = Заг+"По бухгалтерским данным. По фирме "+выбФирма+". ";
    Иначе                      
        ТекстЗапр = ТекстЗапр+"
            | WHERE ($Регистр.Остатки.Фирма NOT IN (SELECT VAL FROM #Группа))";
 
        Заг = Заг+"По торговым данным. ";
    КонецЕсли;                      
    ТекстЗапр = ТекстЗапр+"
        | AND ($Регистр.Остатки.Склад IN (SELECT VAL FROM #Группа))";    
 
        
    ТекстЗапроса = ТекстЗапроса + "
        | AND ($Регистр.Остатки.Кво<10)";
    
    Запр=СоздатьОбъект("ODBCRecordset");
   bananan
 
64 - 29.12.12 - 15:32
(62)Отладку синтаксиса - синтаксических ошибок не обнаружено
отладка запросов - запросов не обнаружено
   Стрелок
 
65 - 29.12.12 - 15:32
весь текст запроса без комментированных строк
   Стрелок
 
66 - 29.12.12 - 15:33
бл... запрос.отладка(1)
   bananan
 
67 - 29.12.12 - 15:35
(65) Весб текст без коментов:
ТекстЗапроса = "
                    |select         
                    | $Регистр.Остатки.Фирма AS [Фирма $Справочник.Фирмы]
                    | ,$Регистр.Остатки.ТМЦ AS [ТМЦ $Справочник.ТМЦ]
                    | ,$Регистр.Остатки.Кво AS Кво";

    Если Режим = "Подробно" Тогда
        ТекстЗапр = ТекстЗапр+"
                    | ,$Регистр.Остатки.Партия";
    КонецЕсли;           
    
    ТекстЗапроса = ТекстЗапроса + "
                    | ,$Регистр.Остатки.СуммаГрн AS СуммаГрн
                    | ,$Регистр.Остатки.СуммаБезНДС AS СуммаБезНДС
                    | ,$Регистр.Остатки.СуммаОсн AS СуммаОсн
                    | ,$Регистр.Остатки.Наценка AS Наценка";
    ТекстЗапроса = ТекстЗапроса + "
        | FROM $Регистр.Остатки AS Рег";
    Если (сВидУчета.ПолучитьЗначение(сВидУчета.ТекущаяСтрока())="Бухгалтерия") Тогда
        ТекстЗапр = ТекстЗапр+"
            | WHERE ($Регистр.Остатки.Фирма IN (SELECT VAL FROM #Группа))";
 
        Заг = Заг+"По бухгалтерским данным. По фирме "+выбФирма+". ";
    Иначе                      
        ТекстЗапр = ТекстЗапр+"
            | WHERE ($Регистр.Остатки.Фирма NOT IN (SELECT VAL FROM #Группа))";
 
        Заг = Заг+"По торговым данным. ";
    КонецЕсли;                      
    ТекстЗапр = ТекстЗапр+"
        | AND ($Регистр.Остатки.Склад IN (SELECT VAL FROM #Группа))";    
 
        
    ТекстЗапроса = ТекстЗапроса + "
        | AND ($Регистр.Остатки.Кво<10)";
    
    Запр=СоздатьОбъект("ODBCRecordset");
   bananan
 
68 - 29.12.12 - 15:35
(66) А это дает только вывод текста запроса в окне сообщений
   bananan
 
69 - 29.12.12 - 15:37
+(68) Там что-то много моего кода в запрос не вхоидт
   bananan
 
70 - 29.12.12 - 15:37
Если (сВидУчета.ПолучитьЗначение(сВидУчета.ТекущаяСтрока())="Бухгалтерия") Тогда
        ТекстЗапр = ТекстЗапр+"
            | WHERE ($Регистр.Остатки.Фирма IN (SELECT VAL FROM #Группа))";
 
        Заг = Заг+"По бухгалтерским данным. По фирме "+выбФирма+". ";
    Иначе                      
        ТекстЗапр = ТекстЗапр+"
            | WHERE ($Регистр.Остатки.Фирма NOT IN (SELECT VAL FROM #Группа))";
 
        Заг = Заг+"По торговым данным. ";
    КонецЕсли;                      
    ТекстЗапр = ТекстЗапр+"
        | AND ($Регистр.Остатки.Склад IN (SELECT VAL FROM #Группа))";    
 
        
    ТекстЗапроса = ТекстЗапроса + "
        | AND ($Регистр.Остатки.Кво<10)";
    
    Запр=СоздатьОбъект("ODBCRecordset");
   bananan
 
71 - 29.12.12 - 15:37
Пардон 70 - ошибочно кинул..
   mehfk
 
72 - 29.12.12 - 15:39
(0)
Сравни
ТекстЗапроса = "
                    |select         
                    | Регистр.Остатки.Фирма AS [Фирма $Справочник.Фирмы]
                    | Регистр.Остатки.Кво AS   [Кво $Регистр.Остатки.Кво]
                    | FROM $Регистр.Остатки as Рег                
                    | WHERE $Регистр.Остатки.Кво<10";


и

ТекстЗапроса = "
                    |select         
                    | $Рег.Фирма AS [Фирма $Справочник.Фирмы],
                    | $Рег.Кво AS   Кво
                    | FROM $Регистр.Остатки as Рег
                    | WHERE $Регистр.Остатки.Кво<10";


и сделай выводы
   mehfk
 
73 - 29.12.12 - 15:39
(72)+ fix
ТекстЗапроса = "
                    |select         
                    | $Рег.Фирма AS [Фирма $Справочник.Фирмы],
                    | $Рег.Кво AS   Кво
                    | FROM $Регистр.Остатки as Рег
                    | WHERE $Рег.Кво<10";
   Стрелок
 
74 - 29.12.12 - 15:40
Глава 4: Работа с регистрами
Как известно регистр остатков состоит из 2х таблиц: Итоги и Движения. В таблице итогов хранятся остатки на ТА и конец каждого месяца (или другой период, как установлено в Операции > Управление оперативными итогами > Периодичность сохранения остатков. Для больших регистров не рекомендуется уменьшать это значение). В таблице движений хранятся соответственно движения за весь период.

Для работы с этими таблицами в 1С++ для них есть свои имена
$Регистр.ХХХ – таблица движений регистра ХХХ
$РегистрИтоги.ХХХ – таблица итогов регистра ХХХ

Пример: Получим движения по регистру ОстаткиТоваров у документа Реализация

ТекстЗапроса = "
|SELECT
|    $Рег.Склад as [Склад $Справочник.Склады],
|    $Рег.Товар as [Товар $Справочник.Номенклатура],
|    $Рег.Количество as Количество
|FROM
|    $Регистр.ОстаткиТоваров as Рег
|WHERE
|    Рег.IDDoc = :ВыбДок";

Получение документа из регистра
В зависимости от наличия флага БыстаяОбработкаДвижений (значение флага смотрите в разделе Оптимизация регистров) получается 2 способа

Способ 1: При наличии флага
ТекстЗапроса = "
|SELECT
|    Рег.IDDoc as [Док $Документ],
|    Рег.IDDocDef as Док_вид,
|    $Рег.Склад as [Склад $Справочник.Склады],
|    $Рег.Товар as [Товар $Справочник.Номенклатура],
|    $Рег.Количество as Количество
|FROM
|    $Регистр.ОстаткиТоваров as Рег
|WHERE
|    Рег.IDDoc = :ВыбДок";

Способ 2: Если флаг не стоит
ТекстЗапроса = "
|SELECT
|    Рег.IDDoc as [Док $Документ],
|    Жур.IDDocDef as Док_вид,
|    $Рег.Склад as [Склад $Справочник.Склады],
|    $Рег.Товар as [Товар $Справочник.Номенклатура],
|    $Рег.Количество as Количество
|FROM
|    $Регистр.ОстаткиТоваров as Рег
|INNER JOIN
|    _1Sjourn as Жур ON Жур.IDDoc = Рег.IDDoc
|WHERE
|    Рег.IDDoc = :ВыбДок";

Как всегда, при типизации документа по полю IDDoc не забываем включать в выборку поле IDDocDef.

Виртуальные таблицы
Чтобы получить остаток на некоторую дату, допустим на середину месяца, нужно объединить два запроса: Итоги на конец предыдущего месяца и Обороты с начала месяца по выбранную дату. Чтобы облегчить нам работу были придуманы, так называемые, виртуальные таблицы (не путать с представлениями VIEW), которые являются простыми макроподстановками (хотя на самом деле не такими уж и простыми. С большой вероятностью, если вы сами будете их разворачивать, то у вас получится хуже, т.к. лучше уже просто уже некуда).

Существует несколько видов виртуальных таблиц
Остатки, ОстаткиОбороты, Обороты.
Первые 2 только для регистров остатков, 2 – для оборотного регистра.

Пример: Получим остатки по складу в разрезе товаров на дату
ТекстЗапроса = "
|SELECT
|    Рег.Товар as [Товар $Справочник.Номенклатура],
|    Рег.КоличествоОстаток as Количество
|FROM
|    $РегистрОстатки.ОстаткиТоваров(:ВыбДата,, 
|                               Склад = :ВыбСклад, 
|                               (Товар), (Количество)) as Рег";

Некоторые пояснения к запросу.
Работа ВТ сводится к получению, обработке и преобразованию запроса в вид понятный MSSQL. 
Существуют несколько видов ВТ
$РегистрОстатки.<ИмяРегистра> - предназначена для получения только остатков из регистра (не имеет смысла для оборотного регистра)
$РегистрОбороты.<ИмяРегистра> - только для оборотов
$РегистрОстаткиОбороты.<ИмяРегистра> - и остатки и обороты (тоже только для регистра остатков)

Работа каждой из ВТ впринципе идентична, но есть маленькие нюансы.
$РегистрОстатки.<ИмяРегистра>([<ГраницаРасчета>] [, <Соединение>] [,<Условие>] [,<Измерение>] [,<Ресурс>]) [as <Алиас>]
Все параметры являются необязательными, если их все опустить, получим таблицу, содержащую регистр на ТА. Однако, такой способ получения регистра выполняется немного быстрее, чем стандартный Рег.ВыгрузитьИтоги(ТЗ,1,1). Разница несущественная, но она есть.
Границей расчета не обязательно должна быть какаято дата, это может быть и документ, но тогда нужно применить модификатор "~", т.е. :ГраницаРасчета~ ,где ГраницаРасчета задана как текстовый параметр полученый из СформироватьПозициюДокумента(ТекущийДокумент(),-1)
Соединение конструкция типа join. На языке SQL можно описать дополнительные соединения с таблицами, которые могут быть необходимы для формирования условий в следующем параметре
Условие - конструкция типа where. Позволяет фильтровать результат выборки по какому либо измерению или по нескольким измерениям
В выше приведенном примере в скобках указаны измерения и ресурсы, по которым строится запрос к регистру. Это позволяет уменьшить объем запроса, вернувшегося на клиента. В случае, если требуется построить запрос по нескольким измерениям или рассчитать несколько ресурсов, их указывают в скобках через запятую, например (Товар,Склад) или (Количество,СуммаУпр), либо их вообще можно пропустить ошибкой это не будет, просто в запрос попадут все измерения или все ресурсы.
Возвращаемые поля ресурсов будут иметь вид <ИмяРесурса>Остаток
$РегистрОбороты.<ИмяРегистра>([<НачалоПериода>][, <КонецПериода>][, <Периодичность>][, <Соединение>][,<Условие>][,<Измерение>][,<Ресурс>]) [as <Алиас>]
Как видно здесь добавился параметр КонецПериода и Периодичность. Первый представляет собой обычную дату, а вот периодичность может принимать несколько значений:
Период (Period) - только за период (не разворачивать)
Документ (Document) - разворачивать по документу
День (Day) - разворачивать по дням
Неделя (Week) - разворачивать по неделям
Месяц (Month) - разворачивать по месяцам
Квартал (Quarter) - разворачивать по кварталам
Год (Year) - разворачивать по годам
По умолчанию Период
Здесь возвращаемые поля ресурсов будут иметь вид 
<ИмяРесурса>Приход – сумма прихода в периоде(только для регистра остатков)
<ИмяРесурса>Расход – сумма расхода в периоде(только для регистра остатков)
<ИмяРесурса>Оборот – сумма оборота за период(только для регистра оборотов)
Кроме того, если указана Периодичность существует еще несколько полей
Период – тип datetime, дата начала периода, по которому происходит разворот итогов
ПозицияДокумента – поле date_time_iddoc, определяет документ(существует только если указана периодичность Документ)
ВидДокумента – поле iddocdef, определяет идентификатор вида документа

$РегистрОстаткиОбороты.<ИмяРегистра>([<НачалоПериода>][, <КонецПериода>][, <Периодичность>][,<МетодДополнения>][,<Соединение>][,<Условие>] [,<Измерение>][,<Ресурс>]) [as <Алиас>]
Здесь из нового появился параметр МетодДополнения. Имеет смысл, только когда используется разворот по периодам:
Движения (Actions) – в таблицу включаются обороты по каждому периоду движений, и текущие остатки только по тем комбинациям измерений, по которым были движения в период расчета
ДвиженияИГраницыПериода (ActionsAndPeriodBoundaries) – в таблицу включаются обороты по каждому периоду движений и текущие остатки; также таблица дополняется записями о ненулевых остатках на начало и/или конец на границы периода расчета
Возвращаемые поля ресурсов будут иметь вид 
<ИмяРесурса>НачальныйОстаток – остаток на дату начала
<ИмяРесурса>Приход – сумма прихода в периоде
<ИмяРесурса>Расход – сумма расхода в периоде
<ИмяРесурса>КонечныйОстаток – остаток на дату окончания


К сожалению, пока виртуальные таблицы в DBF версии вообще не работают. Поэтому запрос приведенный выше придется переписать в развернутый вид
|SELECT
|    Рег.Товар as [Товар $Справочник.Номенклатура],
|    SUM(Рег.КоличествоОстаток) as Количество
|FROM
|    (SELECT
|        $Р.Номенклатура AS Товар,
|        $Р.Количество AS КоличествоОстаток
|    FROM 
|        $РегистрИтоги.ОстаткиТоваров as Р
|    WHERE 
|        (period = :ПредМесяц~~)
|        AND ($Р.Склад=:Склад)
|
|    UNION ALL
|
|    SELECT
|        $Р.Номенклатура AS Товар,
|        $Р.Количество * (1 - Р.debkred * 2) AS КоличествоОстаток
|    FROM 
|        $Регистр.ОстаткиТоваров AS Р
|    INNER JOIN 
|        1sjourn jr ON Р.iddoc = jr.iddoc 
|            AND (jr.date BETWEEN :НачалоМесяца~~ AND :ПредДата~~)
|            AND ($ФлагРегистра. ОстаткиТоваров = 1)
|    WHERE 
|        ($Р.Склад=:Склад)
|    ) Рег
|GROUP BY
 
|    Рег.Товар
Замечу, что здесь в обоих случаях алиас таблицы совпадает, но это допустимо только для одного регистра, т.к. регистр имеет одинаковые имена полей в таблицах остатков и оборотов. В общем случае алиасы лучше писать разными.

Здесь параметр ПредМесяц – это дата начала предыдущего месяца от ВыбДата, а ПредДата=ВыбДата-1;

В этом примере мы получим остатки на начало ВыбДата. Если мы хотим на конец, то нужно указывать модификатор :ВыбДата~. Если вообще опустить параметр ВыбДата, то получатся остатки на ТА. Для DBF остатком на конец будет замена ПредДата на ВыбДата, ну а если нужны остатки на ТА, надо условие по датам заменить на
|            AND (jr.date>=НачалоМесяца~~)
 

В модуле документа обычно необходимо получить остатки на документ. Делается это так:

ТекстЗапроса = “
|SELECT
|    Рег.Товар as [Товар $Справочник.Номенклатура],
|    Рег.КоличествоОстаток as Количество,
|    Рег.СуммаОстаток as Сумма
|FROM
|    $РегистрОстатки.ОстаткиТоваров(:ВыбДата~,, 
|                               Склад = :ВыбСклад, 
|                               (Товар), (Сумма, Количество)) as Рег";
RS.УстановитьТекстовыйПараметр("ВыбДата", 
СформироватьПозициюДокумента(ТекущийДокумент(), -1));

В DBF версии нужно сделать условие на время. В системе время хранится не в минутах и секундах, а в миллисекундах, прошедших с начала дня. Поэтому время – уникально для каждого документа.
И еще: в DBF версии в модуле проведения ЗАПРОСЫ НЕ РАБОТАЮТ! Т.к. при этом происходит начало транзакции и драйвер FoxPro не может ничего получить из базы.
Замечание от Uzhast:  На самом деле в модуле проведения запросы работают. Но есть тонкости: выбирать данные из регистра нужно ДО того, как в модуле проведения будет как-либо произведена запись в регистр. После записи в регистр 1С запрещает блокировать таблицу регистра и Fox не может из нее вытащить данные. Запись в регистр происходит, например, при выполнении ДвижениеПриходВыполнить и ПРИ УДАЛЕНИИ ДВИЖЕНИЙ перед перепроведением документа. Поэтому, чтобы можно было использовать запросы в модуле документа, нужно отключить автоматическое удаление движений в "Конфигураторе". Соответственно, при выборке остатков нужно из них, в определенных случаях, вычитать собственные неудаленные движения документа. После выборки данных из регистра удаляем движения документа самостоятельно и делаем проведение с использованием собранных прямым запросом данных.

Вообще, Fox не может вытащить данные потому, что пытается заблокировать таблицу перед чтением. Если 1С ее занимает, то блокировка не удается. Из-за этого, в частности, прямые запросы не работают, если пытаются вытащить данные из регистра, по которому в текущий момент проводится документ. Меня это сильно разозлило - ведь 1С спокойно формирует отчеты по регистрам в момент проведения документов. Немного поковырял драйвер OLE DB (vfpoledb.dll) и повырезал там вызовы функции LockFile. В результате, теперь прямые запросы работают, даже если в этот момент проводится документ. Вероятно, и запросы к регистру в модуле проведения будут работать после модификации самого регистра. Естественно, такой драйвер нельзя использовать для записи данных в таблицу ДБФ - можно обгадить базу.

Также этот патч решает потенциальную проблему: ведь Fox при выполнении запроса блокирует таблицу. Соответственно, если вдруг кто-то захочет провести документ по регистру, по которому формируется запрос, то его ждет облом. Что при этом будет с 1С - не знаю, но для 1С это явно будет нештатная ситуация. Возможно, такой патч - это аналог скульного NOLOCK'а для ДБФ.
А вот собственно файл http://uzhast.fatal.ru/vfpoledb/


Замечание: Все фильтры нужно накладывать внутри ВТ. Нельзя накладывать фильтр по реквизитам регистра. Это также касается таблицы ОстаткиИОбороты, а для таблицы Обороты можно.

А что если нужно получить остатки отфильтрованные по типу номенклатуры. А для этого нужно использовать 2 параметр ВТ, который называется Соединение

ТекстЗапроса = "
|SELECT
|    Рег.Товар as [Товар $Справочник.Номенклатура],
|    Рег.КоличествоОстаток as Количество
|FROM
|    $РегистрОстатки.ОстаткиТоваров(:ВыбДата~,
|                               INNER JOIN $Справочник.Номенклатура СпрН ON
|                                          СпрН.ID =  Товар AND
|                                          $СпрН.ТипНоменклатуры = :ВыбТип, 
|                               Склад = :ВыбСклад, 
|                               (Товар), (Количество)) as Рег”;

Т.к. в DBF мы формировали запрос без ВТ, то добавить туда еще одно условие не составит труда
|SELECT
|    Рег.Товар as [Товар $Справочник.Номенклатура],
|    SUM(Рег.КоличествоОстаток) as Количество
|FROM
|    (SELECT
|        $Р.Номенклатура AS Товар,
|        $Р.Количество AS КоличествоОстаток
|    FROM 
|        $РегистрИтоги.ОстаткиТоваров as Р
|    INNER JOIN $Справочник.Номенклатура СпрН ON 
|                СпрН.id=Товар
|                AND $СпрН.ТипНоменклатуры = :ВыбТип, 
|    WHERE 
|        (period = :ПредМесяц~~)
|        AND ($Р.Склад=:Склад)
|
|    UNION ALL
|
|    SELECT
|        $Р.Номенклатура AS Товар,
|        $Р.Количество * (1 - Р.debkred * 2) AS КоличествоОстаток
|    FROM 
|        $Регистр.ОстаткиТоваров AS Р
|    INNER JOIN 
|        1sjourn jr ON Р.iddoc = jr.iddoc 
|            AND (jr.date BETWEEN :НачалоМесяца~~ AND :ПредДата~~)
|            AND ($ФлагРегистра. ОстаткиТоваров = 1)
|    INNER JOIN $Справочник.Номенклатура СпрН ON 
|                СпрН.id=Товар
|                AND $СпрН.ТипНоменклатуры = :ВыбТип, 
|    WHERE 
|        ($Р.Склад=:Склад)
|    ) Рег
|GROUP BY
|    Рег.Товар

Таблица ОстаткиИОбороты похоже на таблицу Остатки, только выбирается начальная и конечная даты и периодичность

Без периодичности (за период)
ТекстЗапроса = "
|SELECT
|    Рег.Товар as [Товар $Справочник.Номенклатура],
|    Рег.КоличествоНачальныйОстаток as КоличествоНачОст,
|    Рег.КоличествоПриход as КоличествоПриход,
|    Рег.КоличествоРасход as КоличествоРасход,
|    Рег.КоличествоКонечныйОстаток as КоличествоКонОст,
|    Рег.СуммаНачальныйОстаток as СуммаНачОст,
|    Рег.СуммаПриход as СуммаПриход,
|    Рег.СуммаРасход as СуммаРасход,
|    Рег.СуммаКонечныйОстаток as СуммаКонОст,
|FROM
|    $РегистрОстаткиОбороты.ОстаткиТоваров(:НачДата, :КонДата~,,,
|                               Склад = :ВыбСклад, 
|                               (Товар), (Сумма, Количество)) as Рег";

Для DBF усложняем вариант с остатками:
|SELECT
|    Рег.Товар as [Товар $Справочник.Номенклатура],
|    SUM(Рег.КоличествоНачОст) AS КоличествоНачОст,
|    SUM(Рег.КоличествоПриход) AS КоличествоПриход,
|    SUM(Рег.КоличествоРасход) AS КоличествоРасход,
|    SUM(Рег.КоличествоНачОст) + SUM(Рег.КоличествоПриход) - SUM(Рег.КоличествоРасход) AS КоличествоКонОст
|FROM
|    (SELECT
|        $Р.Номенклатура AS Товар,
|        $Р.Количество AS КоличествоНачОст,
|        $0 AS КоличествоПриход,
|        $0 AS КоличествоРасход
|    FROM 
|        $РегистрИтоги.ОстаткиТоваров as Р
|    WHERE 
|        (period = :ПредМесяц~~)
|        AND($Р.Склад=:Склад)
|
|    UNION ALL
|
|    SELECT
|        $Р.Номенклатура AS Товар,
|        $Р.Количество * (1 - Р.debkred * 2) AS КоличествоНачОст,
|        $0 AS КоличествоПриход,
|        $0 AS КоличествоРасход
|    FROM 
|        $Регистр.ОстаткиТоваров AS Р
|    INNER JOIN 
|        1sjourn jr ON (Р.iddoc = jr.iddoc)
|            AND (jr.date BETWEEN :НачалоМесяца~~ AND :ПредДата~~)
|            AND ($ФлагРегистра. ОстаткиТоваров = 1)
|    WHERE
|        ($Р.Склад=:Склад)
|
|    UNION ALL
|
|    SELECT
|        $Р.Номенклатура AS Товар,
|        $0 AS КоличествоНачОст,
|        (1-Р.debkred)* $Р.Количество AS КоличествоПриход,
|        (Р.debkred)    * $Р.Количество AS КоличествоРасход
|    FROM
|        $Регистр.ОстаткиТоваров AS Р
|    INNER JOIN
|        1sjourn jr ON (Р.iddoc = jr.iddoc)
|            AND (jr.date BETWEEN : НачДата~~ AND : КонДата~~)
|            AND ($ФлагРегистра. ОстаткиТоваров = 1)
|    WHERE
|        ($.Р.Склад=:Склад)
|    ) Рег
|GROUP BY
|    Товар
Здесь стоит остановиться на параметре $0. Это замена числа ноль на 00000000000.0000


С периодичностью
Период может быть: День, Неделя, Месяц, Квартал, Год

ТекстЗапроса = "
|SELECT
|    Рег.Товар as [Товар $Справочник.Номенклатура],
|    Рег.КоличествоНачальныйОстаток as КоличествоНачОст,
|    Рег.КоличествоПриход as КоличествоПриход,
|    Рег.КоличествоРасход as КоличествоРасход,
|    Рег.КоличествоКонечныйОстаток as КоличествоКонОст,
|    Рег.Период Период
|FROM
|    $РегистрОстаткиОбороты.ОстаткиТоваров(:НачДата, :КонДата~, Месяц,,
|                               Склад = :ВыбСклад, 
|                               (Товар), (Количество)) as Рег";
В данном случае в поле период будет начало каждого месяца (периода). Как всегда при указании периода первую дату ставим без модификатора, вторую с модификатором.

Аналогично работает ВТ Обороты, только поля называются <ИмяИзмерения>Оборот

Для ДБФ версии придется немного потрудится.
Сначала сделаем простой запрос с группировкой день
|SELECT
|    Рег.Товар as [Товар $Справочник.Номенклатура],
|    Рег.Период Период,
|    SUM(Рег.Количество) as Количество
|FROM
|    (SELECT
|        $Р.Номенклатура as Товар,
|        $Р.Количество as Количество,
|        jr.date as Период
|    FROM $Регистр.ОстаткиТоваров as Р
|    INNER JOIN 
|        1sjourn jr ON (Р.iddoc = jr.iddoc)
|                And (jr.date BETWEEN :НачДата~~ AND :КонДата~~)
|    WHERE 
|        AND ($ФлагРегистра. ОстаткиТоваров = 1)
|    ) as Рег
|GROUP BY
|    Рег.Товар,
|    Рег.Период
 

Как видно запрос получился очень простой, но абсолютно бестолковый ? . Теперь немного усложним его – сделаем запрос с группировкой неделя. Для этого воспользуемся функцией dow(Дата) которая возвращает номер недели в году, но для операций с датой этого не достаточно, нужно еще использовать преобразование 60*60*24=86400 – число секунд в одном дне. Дело в том, что Фокс работает с датой как и со временем, т.е. Дата-1 отнимет одну секунду от даты и получится что то вроде
01.01.2000: 23:59:59’ вместо просто ’01.01.2000’

|SELECT
|    Рег.Товар as [Товар $Справочник.Номенклатура],
|    Рег.Период Период,
|    SUM(Рег.Количество) as Количество
|FROM
|    (SELECT
|        Рег.Товар,
|        IIF(Рег.Период<:НачДата~~,:НачДата~~,Рег.Период) as Период
|    FROM
|        (SELECT
|            $Р.Номенклатура as Товар,
|            $Р.Количество as Количество,
|            jr.date-dow(jr.date)*86400 as Период
|        FROM $Регистр.ОстаткиТоваров as Р
|        INNER JOIN 
|            1sjourn jr ON (Р.iddoc = jr.iddoc)
|                And (jr.date BETWEEN :НачДата~~ AND :КонДата~~)
|        WHERE 
|            AND ($ФлагРегистра. ОстаткиТоваров = 1)
|        ) as Рег
|    ) as Рег
|GROUP BY
|    Рег.Товар,
|    Рег.Период

 
В этом примере условие IIF(Условие,Правда,Ложь) выполняет роль фильтра, т.к. запрос 1С с группировкой Неделя отрезает все даты меньшие чем дата начала. Сам запрос практически не изменился, разве что для удобства группировок мы создали еше один вложенный SELECT, без которого, впрочем, можно было бы обойтись.

Теперь посмотрим на запрос с группировкой Месяц
|SELECT
|    Рег.Товар as [Товар $Справочник.Номенклатура],
|    Рег.Период Период,
|    SUM(Рег.Количество) as Количество
|FROM
|    (SELECT
|        Рег.Товар,
|        IIF(Рег.Период<:НачДата~~,:НачДата~~,Рег.Период) as Период
|    FROM
|        (SELECT
|            $Р.Номенклатура as Товар,
|            $Р.Количество as Количество,
|            CAST(
|                STR(MONTH(jr.date))+’.01.’+STR(YEAR(jr.date)) 
|            as datetime) as Период
|        FROM $Регистр.ОстаткиТоваров as Р
|        INNER JOIN 
|            1sjourn jr ON (Р.iddoc = jr.iddoc)
|                And (jr.date BETWEEN :НачДата~~ AND :КонДата~~)
|        WHERE 
|            AND ($ФлагРегистра. ОстаткиТоваров = 1)
|        ) as Рег
|    ) as Рег
|GROUP BY
|    Рег.Товар,
|    Рег.Период

Как и в предыдущем примере условие IIF(Условие,Правда,Ложь) выполняет роль фильтра, а вот подзапрос немного изменился. Функция MONTH(дата)  возвращает месяц даты, а YEAR(дата) – год.
Обратите внимание на формат даты: «ММ.ДД.ГГГГ». Функция STR(Ч) преобразовывает результат в строку, а CAST(Строка as datetime) – обратно в дату. Таким образом из даты ‘23.04.2006’ мы получили дату ’01.04.2006’

Самой сложной операцией будет группировка Квартал.
|SELECT
|    Рег.Товар as [Товар $Справочник.Номенклатура],
|    Рег.Период Период,
|    SUM(Рег.Количество) as Количество
|FROM
|    (SELECT
|        Рег.Товар,
|        IIF(Рег.Период<:НачДата~~,:НачДата~~,Рег.Период) as Период
|    FROM
|        (SELECT
|            $Р.Номенклатура as Товар,
|            $Р.Количество as Количество,
|            CAST(
|                STR(
|                    IIF(MONTH(jr.date)<4, '01',
|                        IIF(MONTH(jr.date)<7, '04',
|                            IIF(MONTH(jr.date)<10, '07',10
|                            )
|                        )
|                    )
|                )+’.01.’+STR(YEAR(jr.date)) 
|            as datetime) as Период
|        FROM $Регистр.ОстаткиТоваров as Р
|        INNER JOIN 
|            1sjourn jr ON (Р.iddoc = jr.iddoc)
|                And (jr.date BETWEEN :НачДата~~ AND :КонДата~~)
|        WHERE 
|            AND ($ФлагРегистра. ОстаткиТоваров = 1)
|        ) as Рег
|    ) as Рег
|GROUP BY
|    Рег.Товар,
|    Рег.Период

 
Здесь делается проверка на принадлежноть месяца к определенному кварталу и производится подменена номера месяца на начало квартала. Так, дата ’12.08.2006’ преобразуется в дату ’01.07.2006’

Последняя группировка - Год
|SELECT
|    Рег.Товар as [Товар $Справочник.Номенклатура],
|    Рег.Период Период,
|    SUM(Рег.Количество) as Количество
|FROM
|    (SELECT
|        Рег.Товар,
|        IIF(Рег.Период<:НачДата~~,:НачДата~~,Рег.Период) as Период
|    FROM
|        (SELECT
|            $Р.Номенклатура as Товар,
|            $Р.Количество as Количество,
|            CAST(
|                STR(’01.01.’+STR(YEAR(jr.date)) 
|            as datetime) as Период
|        FROM $Регистр.ОстаткиТоваров as Р
|        INNER JOIN 
|            1sjourn jr ON (Р.iddoc = jr.iddoc)
|                And (jr.date BETWEEN :НачДата~~ AND :КонДата~~)
|        WHERE 
|            AND ($ФлагРегистра. ОстаткиТоваров = 1)
|        ) as Рег
|    ) as Рег
|GROUP BY
|    Рег.Товар,
|    Рег.Период

Запрос тоже очень простой - от даты остается только номер года, а месяц и день заменяются на 01.01
 

Теперь вернемся к примеру СКЛ с периодичностью и попробуем переложить его на ДБФ запрос.
Т.к. запросы довольно сильно отличаются, воспользуемся дополнительными переменными
естьДень=1; естьМесяц=1; естьКвартал=0;
Если Группировка = "день" Тогда
        ПеременнаяПериода = "Рег.Период";
ИначеЕсли Группировка = "неделя" Тогда
        ПеременнаяПериода = "Рег.Период-dow(Рег.Период)*86400";
ИначеЕсли Группировка = "месяц" Тогда
        ПеременнаяПериода = "CAST(STR(MONTH(Рег.Период))+'.01.'+STR(YEAR(Рег.Период)) as datetime)";
    естьДень=0;
ИначеЕсли Группировка = "квартал" Тогда
        ПеременнаяПериода = "CAST(
        |            STR(
        |                IIF(MONTH(jr.date)<4, '01',
        |                    IIF(MONTH(jr.date)<7, '04',
        |                        IIF(MONTH(jr.date)<10, '07',10
        |                        )
        |                    )
        |                )
        |            )+’.01.’+STR(YEAR(jr.date)) 
        |            as datetime)";

    естьДень=0; естьКвартал=1;
ИначеЕсли Группировка = "год" Тогда
        ПеременнаяПериода = "CAST('01.01.'+STR(YEAR(Рег.Период) as datetime)";
    естьДень=0; естьМесяц=0;
КонецЕсли;

ТекстЗапроса = "
|SELECT
|    Рег.Товар as [Товар $Справочник.Номенклатура],
|    Рег.Период as Период,
|    SUM(Рег.КоличествоНачОст) AS КоличествоНачОст,
|    SUM(Рег.КоличествоПриход) AS КоличествоПриход,
|    SUM(Рег.КоличествоРасход) AS КоличествоРасход,
|    SUM(Рег.КоличествоНачОст) + SUM(Рег.КоличествоПриход) - SUM(Рег.КоличествоРасход) AS КоличествоКонОст
|FROM
|    (SELECT
|        Рег.Товар,
|        IIF("+ПеременнаяПериода +"<:НачДата~~,:НачДата~~,
|            "+ПеременнаяПериода +"
|        ) as Период,
|        Рег.КоличествоНачОст,
|        Рег.КоличествоПриход,
|        Рег.КоличествоРасход
|    FROM
|        (SELECT
|            $Р.Номенклатура AS Товар,
|            Р.period as Период,
|            $Р.Количество AS КоличествоНачОст,
|            $0 AS КоличествоПриход,
|            $0 AS КоличествоРасход
|        FROM 
|            $РегистрИтоги.ОстаткиТоваров as Р
|        WHERE 
|            (period = :ПредМесяц~~)
|            AND($Р.Склад=:Склад)
|
|        UNION ALL
|
|        SELECT
|            $Р.Номенклатура AS Товар,
|            jr.date as Период,
|            $Р.Количество * (1 - Р.debkred * 2) AS КоличествоНачОст,
|            $0 AS КоличествоПриход,
|            $0 AS КоличествоРасход
|        FROM 
|            $Регистр.ОстаткиТоваров AS Р
|        INNER JOIN 
|            1sjourn jr ON (Р.iddoc = jr.iddoc)
|                AND (jr.date BETWEEN :НачалоМесяца~~ AND :ПредДата~~)
|                AND ($ФлагРегистра. ОстаткиТоваров = 1)
|        WHERE
|            ($Р.Склад=:Склад)
|
|        UNION ALL
|
|        SELECT
|            $Р.Номенклатура AS Товар,
|            jr.date as Период,
|            $0 AS КоличествоНачОст,
|            (1-Р.debkred)* $Р.Количество AS КоличествоПриход,
|            (Р.debkred)    * $Р.Количество AS КоличествоРасход
|        FROM
|            $Регистр.ОстаткиТоваров AS Р
|        INNER JOIN
|            1sjourn jr ON (Р.iddoc = jr.iddoc)
|                AND (jr.date BETWEEN : НачДата~~ AND : КонДата~~)
|                AND ($ФлагРегистра. ОстаткиТоваров = 1)
|        WHERE
|            ($.Р.Склад=:Склад)
|        ) Рег
|    ) Рег
|GROUP BY
|    Товар,
|    Период
|";

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

Во всех предыдущих примерах на выходе получалась таблица значений с одним реквизитом «Товар». Но что делать, в случае, когда реквизитов несколько, например Товар и Период? Работать с такой таблицей не удобно, т.к. ТЗ, в отличие от стандартного запроса, не умеет получать промежуточные итоги по реквизиту, поэтому приходится сортировать запрос, сравнивать предыдущий товар с текущим и выводить результат. Все это усложняет отображение результата и программный код. Для упрощения кода может помочь ИндексированнаяТаблица. Вот пример показывающий как она работает:

ТЗ=Запрос.ВыполнитьИнструкцию(ТекстЗапроса);
ИТЗТовары=СоздатьОбъект("ИндексированнаяТаблица");
ИТЗТовары.Загрузить(ТЗ);
ИТЗТовары.Группировать("Товар:Товар; Период: Период"," КоличествоНачОст, КоличествоПриход, КоличествоРасход,КоличествоКонОст");
ИТЗТовары.ВыбратьСтроки();
Пока ИТЗТовары.ПолучитьСтроку()=1 Цикл
    итзПериод=ИТЗТовары.тзПотомки;
итзПериод.ВыбратьСтроки();
ИтогКолвоНач = ИТЗТовары.КоличествоНачОст;
ИтогКолвоПриход = ИТЗТовары.КоличествоПриход;
ИтогКолвоРасход = ИТЗТовары.КоличествоРасход;
ИтогКолвоКон = ИТЗТовары.КоличествоКонОст;
Пока итзПериод.ПолучитьСтроку()=1 Цикл
КолвоНач = ИТЗТовары.КоличествоНачОст;
КолвоПриход = ИТЗТовары.КоличествоПриход;
КолвоРасход = ИТЗТовары.КоличествоРасход;
КолвоКон = ИТЗТовары.КоличествоКонОст;
КонецЦикла;
КонецЦикла;

В этом примере метод Группировать сам сгруппирует линейную таблицу по реквизитам Товар,Период и подсчитает итоги по колонкам КоличествоНачОст, КоличествоПриход, КоличествоРасход,КоличествоКонОст. Фактически это аналог работы стандартного Запроса с группировками Товар и Период. Однако, не стоит делать группировки по приведенным полям (в нашем случае это поле Товар), т.к. для сравнения строк 1С делает подзапрос к базе и все ускорение сводится на «нет». Лучше завести дополнительное поле Товар_ИД, которое будет содержать текстовый идентификатор товара и группировать по нему. Получить представление товара можно будет всегда, т.к. метод Группировать() не удаляет «лишние» поля,как это делает метод Свернуть(), а поля Товар и Товар_ИД по сути идентичны и уникальны для всей таблицы.

Оптимизация регистров
Существует всего 3 способа.
1)    Установка флага БыстраяОбработкаДвижений. Очень полезен при частых расчетах регистра задним числом, а также при снятии отчета за не полный период.
При установке этого флага в таблицу движений регистра добавляется поле Date_Time_IDDoc и IDDocDef, что убирает необходимость присоединения таблицы _1SJourn для определения даты.
2)    Правильная расстановка измерений ресурса: Рассматриваем только те, по которым идет отбор. Сначала идет измерение с самым большим количеством значений, потом поменьше и в конце измерения по которым менее всего нужен отбор. Это связано с наличием одного индекса по всем измерениям.
Пример: Регистр.Партии: Склад, Товар, Партия, Фирма
Отбор по партии практически не нужен, поэтому правильно расположить измерения так: Товар, Склад, Фирма, Партия
3)    Установка флага отбор движений у измерения

1 и 3 способы приводят к заметному увеличению индекса, поэтому нужно помнить о балансе записи и чтения.
   monsterZE
 
75 - 29.12.12 - 15:46
(70) ты еще не забудь уточнить - что такое #Группа

| AND ($Регистр.Остатки.Склад IN (SELECT VAL FROM #Группа))"; 
 

когда пихаешь в запрос два условия по выбору из разных групп..
   bananan
 
76 - 29.12.12 - 15:46
(74) Тут читать минут 15 не меньше.
А вопрос у меня простой почему в текст запроса мой код не вносит текст?
В результате работы скрипта текст запроса имеет такой вид:
select        
 sp1855 AS [Фирма $Справочник.Фирмы]
 ,sp1053 AS [ТМЦ $Справочник.ТМЦ]
 ,sp1055 AS Кво
 ,sp1056 AS СуммаГрн
 ,sp1057 AS СуммаБезНДС
 ,sp1058 AS СуммаОсн
 ,sp1059 AS Наценка
FROM ra1051 AS Рег
 AND (sp1055<10)
Т.е несколько строк из моего кода почему-то не выполнилось
После  FROM ra1051 AS Рег
пошло сразу  AND (sp1055<10), а WHERE пропало
   monsterZE
 
77 - 29.12.12 - 15:49
>Тут читать минут 15 не меньше.
>А вопрос у меня простой..
=))))))))))
   Стрелок
 
78 - 29.12.12 - 15:50
задолбал земляк. думай - почему не добпаляется текст в запрос - условие - а оно выполняется?
   Stella0608
 
79 - 29.12.12 - 15:50
А можно повторить вопрос для тех кому некогда читать все 15 минут? :)
   Стрелок
 
80 - 29.12.12 - 15:50
(76) бл.. это ДОКУМЕНТАЦИЯ!!!!!
   Stella0608
 
81 - 29.12.12 - 15:51
Короче для ленивых и занятых вроде меня кидай нынешний запрос и что именно не нравится :).
   Стрелок
 
82 - 29.12.12 - 15:52
щас доиграешься - всю доку кину (12 глав)
   Stella0608
 
83 - 29.12.12 - 15:52
(82) Доку скачать в тырнете можно, или ну вообще влом? :).
   Стрелок
 
84 - 29.12.12 - 15:52
(81) я так понял - отчёт по остаткам на ++
   monsterZE
 
85 - 29.12.12 - 15:53
=))))) тс, ты как будто из копипаста программишь
половина
ТекстЗапроса
вторая
ТекстЗапр
мля, почему в запросе этого нет?
   monsterZE
 
86 - 29.12.12 - 15:54
(0) кароче в нг читать доку, которая еще со вчера у тебя в мейл-боксе лежит.. и думать.. читать, пробывать примеры и снова думать. =)
   sapphire
 
87 - 29.12.12 - 15:56
>>В результате работы скрипта текст запроса имеет такой вид:

Естественно, такой вид и должен быть коли выполнить не могет....


Ааа... Я в печали. Почти в трауре...
   Stella0608
 
88 - 29.12.12 - 15:57
Дайте актуальный код и ошибку :).
   sapphire
 
89 - 29.12.12 - 15:58
(79) А оно тебе надо? Сей товарищь вообще с трудом понимает что пишет
   Stella0608
 
90 - 29.12.12 - 15:59
(90) Я понимаю, надо голову разгрузить немного, а мне тут еще 2 часа торчать :).
   sapphire
 
91 - 29.12.12 - 16:00
(88) см (51)
   monsterZE
 
92 - 29.12.12 - 16:01
горящий топик =) всех с наступающим НГ! всех благ!
   sapphire
 
93 - 29.12.12 - 16:02
(90) Короче... Мастерит паренек прямой запрос типа остатков,
естественно, читать ничего не хочет, использует форум как копи-пасту... В итоге, когда собирает текст запроса, то текст запроса не содержит конструкции FROM в SELECT-е.
   sapphire
 
94 - 29.12.12 - 16:03
(90) Я ему предложил использовать конструкцию try-except-endtry для отладки запроса, т.е. выводит парсером текст который пытается скормить соединению с СУБД.
   Stella0608
 
95 - 29.12.12 - 16:07
Мда, мой моск в субботу плохо соображает.
Навскидку:
1) ТекстЗапроса - если уж переменная так обозвана, то везде;
2) From перед Where
3) В Where использовать AND, OR, ну и т.п.... несколько Where не нужны
4) База SQL? Если да, иногда сильно оптимальнее использовать виртуальные таблицы регистров, и уже там накладывать ограничения на склады и т.п...
   Stella0608
 
96 - 29.12.12 - 16:08
Правда я думаю, что он вряд ли сообразит то, что я написала :).
   sapphire
 
97 - 29.12.12 - 16:10
(95) Адресуй это ТС :)
   bananan
 
98 - 29.12.12 - 16:10
Где-то здесь ошибка (проверял - в окне сообщений выводится и Выбрана фирма и НЕ Выбрана фирма, но и в том и в другом случае в текст запроса не добавляется почему-то соответственное WHERE
   Mikeware
 
99 - 29.12.12 - 16:10
(96) по-идее, он должен тебя спросить: "ты это с кем разговаривала?"
:-)
   sapphire
 
100 - 29.12.12 - 16:10
(96) Вот и я о том же, что человек даже не смотрит что он копи-пастит.
  1  2   

Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Тема не обновлялась длительное время, и была помечена как архивная. Добавление сообщений невозможно.
Но вы можете создать новую ветку и вам обязательно ответят!
Каждый час на Волшебном форуме бывает более 2000 человек.
Рекламное место пустует