|
v7: 1С++ | ☑ | ||
---|---|---|---|---|
0
bananan
28.12.12
✎
18:35
|
Добрый вечер, может еще кто есть?
Значит так... Решил я "набить" руку по Запросам под 1С++. Взял отчет ОстаткиТМЦ из конфигураци, хочу "заточить" его под 1с++.. понятно пока только пробую. Т.е. то, что ейчас в тексте запроса не совсем то, что будет в результате этой работы... ТАк вот текст запроса у меня такой: ТекстЗапроса = " |select | Регистр.Остатки.Фирма AS [Фирма $Справочник.Фирмы] | Регистр.Остатки.Кво AS [Кво $Регистр.Остатки.Кво] | FROM $Регистр.Остатки as Рег | WHERE $Регистр.Остатки.Кво<10"; Так ругается: Incorrect syntax near 'Регистр'. В чем у меня ошибка? |
|||
1
DEVIce
28.12.12
✎
18:39
|
В селект-листе наверной надо писать назначенный алиас, как ты думаешь?
Select Рег.Фирма .... И так далее. Ты в запросах-то вообще шаришь? |
|||
2
DEVIce
28.12.12
✎
18:40
|
А так вообще не вижу смысла НАЧИНАТЬ ковырять 1С++. Его надо уже заканчивать ковырять и заниматьчя v8.
|
|||
3
GLazNik
28.12.12
✎
18:41
|
+(1) Или $Регистр.Остатки.Фирма
|
|||
4
КонецЦикла
28.12.12
✎
18:42
|
$Рег.Количество AS Кво
|
|||
5
Mikeware
28.12.12
✎
18:42
|
(2) знание сиквельных запросов очень помогает при переходе на снеговика.
а если еще пользуешься не "чистым" 1с++, а классом ПоставшикДанных - еще более... |
|||
6
DEVIce
28.12.12
✎
18:44
|
(5) Это да, согласен. Самому здорово помогло. Если по работе приходилось ковырять 1С++ и прямые запросы, то без вопросов. Но НАЧИНАТЬ ковырять 1С++, чтобы было проще освоить v8 - а нафига?
|
|||
7
Sereja
28.12.12
✎
18:48
|
(0) Скачай конструктор запросов для 1cpp и тебе станет легче
|
|||
8
КонецЦикла
28.12.12
✎
18:51
|
(6) А кто тебе сказал, что автор собирается осваивать и что это ему нужно/пригодиццо :)
|
|||
9
Андрей_Андреич
naïve
28.12.12
✎
18:52
|
(6) Человеку кушать хочется. За что платят - на том и работаем.
|
|||
10
bananan
28.12.12
✎
19:00
|
(7) Не в курсе где его можно скачать?
|
|||
11
bananan
28.12.12
✎
19:21
|
У меня конфигурация для Украины.
Регистр.Остатки.Кво - это количество остатков. Но, выдает: Текст Запроса такой: ТекстЗапроса = " |select | $Регистр.Остатки.Фирма AS [Фирма $Справочник.Фирмы] | $Регистр.Остатки.Кво AS Кво | FROM $Регистр.Остатки as Рег | WHERE $Регистр.Остатки.Кво<10"; Incorrect syntax near 'sp1055'. |
|||
12
Дык ё
28.12.12
✎
19:24
|
(11) будь мужиком, поставь запятую :-)
|
|||
13
bananan
28.12.12
✎
19:25
|
(12) :) Спасибо!
|
|||
14
Mikeware
28.12.12
✎
19:26
|
(12) тут не запятую надо ставить, а читать документацию....
|
|||
15
EvgeniuXP
28.12.12
✎
19:27
|
(14) в документации написано: поставьте запятую :)
|
|||
16
monsterZE
28.12.12
✎
22:46
|
(0) я тебе на мыло скинул доку.. там черным по русскому. =) и про регистры в том числе.
|
|||
17
bezgudroman
28.12.12
✎
22:50
|
Да, маны курить ему прийдется..
|
|||
18
Злопчинский
28.12.12
✎
22:54
|
В документации ненаписано достаточно много.. документация - она как паззл... от 3 до 5
|
|||
19
bananan
29.12.12
✎
11:48
|
Доброе утро!
Написал такой код: ТекстЗапроса = " |select | $Регистр.Остатки.Фирма AS [Фирма $Справочник.Фирмы] | ,$Регистр.Остатки.ТМЦ AS [ТМЦ $Справочник.ТМЦ] | ,$Регистр.Остатки.Кво AS Кво"; Если Режим = "Подробно" Тогда ТекстЗапр = ТекстЗапр+" | ,$Регистр.Остатки.Партия"; КонецЕсли; ТекстЗапроса = ТекстЗапроса + " | ,$Регистр.Остатки.СуммаГрн AS СуммаГрн | ,$Регистр.Остатки.СуммаБезНДС AS СуммаБезНДС | ,$Регистр.Остатки.СуммаОсн AS СуммаОсн | ,$Регистр.Остатки.Наценка AS Наценка"; Если (сВидУчета.ПолучитьЗначение(сВидУчета.ТекущаяСтрока())="Бухгалтерия") Тогда ТекстЗапр = ТекстЗапр+" | WHERE $Регистр.Остатки.Фирма IN (SELECT VAL FROM #Группа)"; Заг = Заг+"По бухгалтерским данным. По фирме "+выбФирма+". "; Запр=СоздатьОбъект("ODBCRecordset"); ТЗ = Запр.ВыполнитьИнструкцию(ТекстЗапроса); Запр.УложитьСписокОбъектов(выбФирма, "#Группа","Фирма"); Выдает: Запр.УложитьСписокОбъектов(выбФирма, "#Группа","Фирма");; {\\SERVER12\VPKTEST$\EXTFORMS\ЗАЛИШКИ ТМЦ.ERT(88)}: Недопустимое значение третьего аргумента метода! Фирма у меня есть в селекте... Что здесь не так? |
|||
20
Mikeware
29.12.12
✎
11:49
|
(19) ДНК
|
|||
21
vinogradъ
29.12.12
✎
12:01
|
(19) забей, пиши ещё
|
|||
22
bananan
29.12.12
✎
12:06
|
(20)(21) Так в чем ошибка?
|
|||
23
sapphire
29.12.12
✎
12:06
|
УложитьСписокОбъектов(<?>,<?>,<?>)
Синтаксис: PutObjectList(ObjList, strTableName, strRefKinde) Назначение: сохраняет список объектов во временной таблице MS SQL. Идентификаторы объектов из списка ObjList сохраняются во временной таблице strTableName. Таблица имеет единственное поле val char(9). Имя таблицы должно начинаться с символа «#». Если strRefKinde идентификатор иерархического справочника, то таблица будет содержать элементы иерархически принадлежащие группам переданным в списке. (Подобно оператору «в» стандартного языка запросов 1С.) Параметры: - ObjList (СписокЗначений/АгрегатныйТип): список для сохранения или элемент справочника, группа справочника, документ и т.п.; - strTableName (строка): имя таблицы; - strRefKinde (строка): вид справочника для иерархического включения элементов или вид плана счетов для иерархического включения счетов; |
|||
24
sapphire
29.12.12
✎
12:07
|
Запр.УложитьСписокОбъектов(выбФирма, "#Группа","Фирмы");
|
|||
25
sapphire
29.12.12
✎
12:07
|
- strRefKinde (строка): вид справочника для иерархического включения элементов или вид плана счетов для иерархического включения счетов;
|
|||
26
sapphire
29.12.12
✎
12:09
|
Запр=СоздатьОбъект("ODBCRecordset");
Запр.УложитьСписокОбъектов(выбФирма, "#Группа","Фирмы"); // Было "Фирма", а нужен вид справочника, значит "Фирмы" ТЗ = Запр.ВыполнитьИнструкцию(ТекстЗапроса); |
|||
27
bananan
29.12.12
✎
12:11
|
(23)-(26) Спасибо
|
|||
28
bananan
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' |
|||
29
bananan
29.12.12
✎
13:00
|
+(28) Запрашиваем у Справочника Склады, вроде все так, а не так ведь
|
|||
30
bananan
29.12.12
✎
13:11
|
Почему столбец инвалидный?!
|
|||
31
sapphire
29.12.12
✎
13:11
|
try
Запр.УложитьСписокОбъектов(выбСклад, "#Группа","Склады"); except Message(ОписаниеОшибки()); Meta=CreateObject("MetaDataWork"); Message("===== Запрос в t-SQL ======"); Message(Meta.ОбрМетаСКЛ(ТекстЗапр)); Message("===========++++++++++++++++"); endtry; |
|||
32
bananan
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; ТЗ.ВыбратьСтроку(); |
|||
33
Sereja
29.12.12
✎
13:18
|
||||
34
sapphire
29.12.12
✎
13:20
|
Запр=СоздатьОбъект("ODBCRecordset");
Запр.Отладка(1); try Запр.УложитьСписокОбъектов(выбСклад, "#Группа","Склады"); ТЗ = Запр.ВыполнитьИнструкцию(ТекстЗапроса); ТЗ.ВыбратьСтроку(); except Message(ОписаниеОшибки()); Meta=CreateObject("MetaDataWork"); Message("===== Запрос в t-SQL ======"); Message(Meta.ОбрМетаСКЛ(ТекстЗапр)); Message("===========++++++++++++++++"); endtry; |
|||
35
sapphire
29.12.12
✎
13:22
|
(33) Нуна все эти конструкторы... В 1С особенно.
Писари 1С этими конструкторами только галиматью писать умеют |
|||
36
bananan
29.12.12
✎
13:23
|
(34) Не понял...
(35) и никакого конструктора я не применяя - пишу сам |
|||
37
Sereja
29.12.12
✎
13:23
|
(35) Так не используй. Я ж не тебе ссылку даю.
|
|||
38
bananan
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 ===========++++++++++++++++ |
|||
39
bananan
29.12.12
✎
13:35
|
Перед тем как добавил на проверку склада. Фира - его устраивал - не ругался, а теперь ругается
|
|||
40
bananan
29.12.12
✎
13:50
|
Помогите!
|
|||
41
bananan
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 ===========++++++++++++++++ |
|||
42
bananan
29.12.12
✎
14:18
|
Здесь есть кто-нибудь живой???
|
|||
43
bananan
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); ТЗ = Запр.ВыполнитьИнструкцию(ТекстЗапроса); Запр.УложитьСписокОбъектов(выбФирма, "#Группа","Фирмы"); ТЗ.ВыбратьСтроку(); |
|||
44
bananan
29.12.12
✎
14:31
|
Все равно віждает все ту же ошибку ODBC SQL Server Driver][SQL Server]Invalid column name 'sp1855
|
|||
45
bananan
29.12.12
✎
14:32
|
Ща буду писать по-новой, блин
|
|||
46
kiruha
29.12.12
✎
14:34
|
FROM
|
|||
47
kiruha
29.12.12
✎
14:35
|
Где ???
|
|||
48
kiruha
29.12.12
✎
14:36
|
Б-ть
|
|||
49
bananan
29.12.12
✎
14:39
|
(45)-(48) Не понял
|
|||
50
kiruha
29.12.12
✎
14:45
|
Отсутствует секция FROM
элементарный учебник http://www.sql-tutorial.ru/ru/book_select_statement.html |
|||
51
bananan
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
|
ммммммммммммммммммммммаааааааааааааааааааааатььь....
Автор, ты бы хотя бы синтаксис скуля почитал... Примитивнейший... Какое слово за каким должно идти... |
|||
53
bananan
29.12.12
✎
14:50
|
(52) От блин, да знаю я синтаксис невнимательность просто... вот и перепутал местами Фром и Вера
|
|||
54
bananan
29.12.12
✎
14:51
|
(52) А за подсказку спасибо
|
|||
55
kiruha
29.12.12
✎
15:04
|
там у тебя еще куча ошибок
лучше почитать день SQL учебник - пригодится и для работы и для 8.2 1С++ это всего лишь надстройка над языком SQL |
|||
56
bananan
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
|
сдаётся мне это кто то из гуру тролит. уж совсем по-тупому
|
|||
58
bananan
29.12.12
✎
15:25
|
(57) когда кажется - крестится надо. Я скорее начинающий (не смотря на не малое пребывание на этом форуме)
|
|||
59
bananan
29.12.12
✎
15:26
|
подскажите что там с AND?
|
|||
60
Стрелок
29.12.12
✎
15:28
|
(58) читайте документацию!!!!
|
|||
61
bananan
29.12.12
✎
15:29
|
(60) Обширный и обстоятельный ответ
|
|||
62
Стрелок
29.12.12
✎
15:29
|
это что
Заг = Заг+"По торговым данным. "; КонецЕсли; ТекстЗапр = ТекстЗапр+" | AND ($Регистр.Остатки.Склад IN (SELECT VAL FROM #Группа))"; ты бл хоть отладку включал? |
|||
63
bananan
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"); |
|||
64
bananan
29.12.12
✎
15:32
|
(62)Отладку синтаксиса - синтаксических ошибок не обнаружено
отладка запросов - запросов не обнаружено |
|||
65
Стрелок
29.12.12
✎
15:32
|
весь текст запроса без комментированных строк
|
|||
66
Стрелок
29.12.12
✎
15:33
|
бл... запрос.отладка(1)
|
|||
67
bananan
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"); |
|||
68
bananan
29.12.12
✎
15:35
|
(66) А это дает только вывод текста запроса в окне сообщений
|
|||
69
bananan
29.12.12
✎
15:37
|
+(68) Там что-то много моего кода в запрос не вхоидт
|
|||
70
bananan
29.12.12
✎
15:37
|
Если (сВидУчета.ПолучитьЗначение(сВидУчета.ТекущаяСтрока())="Бухгалтерия") Тогда
ТекстЗапр = ТекстЗапр+" | WHERE ($Регистр.Остатки.Фирма IN (SELECT VAL FROM #Группа))"; Заг = Заг+"По бухгалтерским данным. По фирме "+выбФирма+". "; Иначе ТекстЗапр = ТекстЗапр+" | WHERE ($Регистр.Остатки.Фирма NOT IN (SELECT VAL FROM #Группа))"; Заг = Заг+"По торговым данным. "; КонецЕсли; ТекстЗапр = ТекстЗапр+" | AND ($Регистр.Остатки.Склад IN (SELECT VAL FROM #Группа))"; ТекстЗапроса = ТекстЗапроса + " | AND ($Регистр.Остатки.Кво<10)"; Запр=СоздатьОбъект("ODBCRecordset"); |
|||
71
bananan
29.12.12
✎
15:37
|
Пардон 70 - ошибочно кинул..
|
|||
72
mehfk
29.12.12
✎
15:39
|
(0)
Сравни ТекстЗапроса = " |select | Регистр.Остатки.Фирма AS [Фирма $Справочник.Фирмы] | Регистр.Остатки.Кво AS [Кво $Регистр.Остатки.Кво] | FROM $Регистр.Остатки as Рег | WHERE $Регистр.Остатки.Кво<10"; и ТекстЗапроса = " |select | $Рег.Фирма AS [Фирма $Справочник.Фирмы], | $Рег.Кво AS Кво | FROM $Регистр.Остатки as Рег | WHERE $Регистр.Остатки.Кво<10"; и сделай выводы |
|||
73
mehfk
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 способы приводят к заметному увеличению индекса, поэтому нужно помнить о балансе записи и чтения. |
|||
75
monsterZE
29.12.12
✎
15:46
|
(70) ты еще не забудь уточнить - что такое #Группа
| AND ($Регистр.Остатки.Склад IN (SELECT VAL FROM #Группа))"; когда пихаешь в запрос два условия по выбору из разных групп.. |
|||
76
bananan
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 пропало |
|||
77
monsterZE
29.12.12
✎
15:49
|
>Тут читать минут 15 не меньше.
>А вопрос у меня простой.. =)))))))))) |
|||
78
Стрелок
29.12.12
✎
15:50
|
задолбал земляк. думай - почему не добпаляется текст в запрос - условие - а оно выполняется?
|
|||
79
Stella0608
29.12.12
✎
15:50
|
А можно повторить вопрос для тех кому некогда читать все 15 минут? :)
|
|||
80
Стрелок
29.12.12
✎
15:50
|
(76) бл.. это ДОКУМЕНТАЦИЯ!!!!!
|
|||
81
Stella0608
29.12.12
✎
15:51
|
Короче для ленивых и занятых вроде меня кидай нынешний запрос и что именно не нравится :).
|
|||
82
Стрелок
29.12.12
✎
15:52
|
щас доиграешься - всю доку кину (12 глав)
|
|||
83
Stella0608
29.12.12
✎
15:52
|
(82) Доку скачать в тырнете можно, или ну вообще влом? :).
|
|||
84
Стрелок
29.12.12
✎
15:52
|
(81) я так понял - отчёт по остаткам на ++
|
|||
85
monsterZE
29.12.12
✎
15:53
|
=))))) тс, ты как будто из копипаста программишь
половина ТекстЗапроса вторая ТекстЗапр мля, почему в запросе этого нет? |
|||
86
monsterZE
29.12.12
✎
15:54
|
(0) кароче в нг читать доку, которая еще со вчера у тебя в мейл-боксе лежит.. и думать.. читать, пробывать примеры и снова думать. =)
|
|||
87
sapphire
29.12.12
✎
15:56
|
>>В результате работы скрипта текст запроса имеет такой вид:
Естественно, такой вид и должен быть коли выполнить не могет.... Ааа... Я в печали. Почти в трауре... |
|||
88
Stella0608
29.12.12
✎
15:57
|
Дайте актуальный код и ошибку :).
|
|||
89
sapphire
29.12.12
✎
15:58
|
(79) А оно тебе надо? Сей товарищь вообще с трудом понимает что пишет
|
|||
90
Stella0608
29.12.12
✎
15:59
|
(90) Я понимаю, надо голову разгрузить немного, а мне тут еще 2 часа торчать :).
|
|||
91
sapphire
29.12.12
✎
16:00
|
(88) см (51)
|
|||
92
monsterZE
29.12.12
✎
16:01
|
горящий топик =) всех с наступающим НГ! всех благ!
|
|||
93
sapphire
29.12.12
✎
16:02
|
(90) Короче... Мастерит паренек прямой запрос типа остатков,
естественно, читать ничего не хочет, использует форум как копи-пасту... В итоге, когда собирает текст запроса, то текст запроса не содержит конструкции FROM в SELECT-е. |
|||
94
sapphire
29.12.12
✎
16:03
|
(90) Я ему предложил использовать конструкцию try-except-endtry для отладки запроса, т.е. выводит парсером текст который пытается скормить соединению с СУБД.
|
|||
95
Stella0608
29.12.12
✎
16:07
|
Мда, мой моск в субботу плохо соображает.
Навскидку: 1) ТекстЗапроса - если уж переменная так обозвана, то везде; 2) From перед Where 3) В Where использовать AND, OR, ну и т.п.... несколько Where не нужны 4) База SQL? Если да, иногда сильно оптимальнее использовать виртуальные таблицы регистров, и уже там накладывать ограничения на склады и т.п... |
|||
96
Stella0608
29.12.12
✎
16:08
|
Правда я думаю, что он вряд ли сообразит то, что я написала :).
|
|||
97
sapphire
29.12.12
✎
16:10
|
(95) Адресуй это ТС :)
|
|||
98
bananan
29.12.12
✎
16:10
|
Где-то здесь ошибка (проверял - в окне сообщений выводится и Выбрана фирма и НЕ Выбрана фирма, но и в том и в другом случае в текст запроса не добавляется почему-то соответственное WHERE
|
|||
99
Mikeware
29.12.12
✎
16:10
|
(96) по-идее, он должен тебя спросить: "ты это с кем разговаривала?"
:-) |
|||
100
sapphire
29.12.12
✎
16:10
|
(96) Вот и я о том же, что человек даже не смотрит что он копи-пастит.
|
|||
101
Mikeware
29.12.12
✎
16:11
|
(98) в в ДНК у тебя ошибка...
|
|||
102
sapphire
29.12.12
✎
16:11
|
(98) На форуме ошибка?!
|
|||
103
bananan
29.12.12
✎
16:12
|
(95)Понял я тебя единственное что не знаю как делать п.4. из того что ты написал
(101) А ты, видимо ГМО? |
|||
104
Mikeware
29.12.12
✎
16:13
|
(103) Нет. мы все тут совершенно нормальные люди. ибо начинаем не с копипасты, а с чтения документации...
|
|||
105
monsterZE
29.12.12
✎
16:13
|
ты (85) читал? =)
там ответ, почему у тебя в запрос условия не добавляются |
|||
106
Stella0608
29.12.12
✎
16:15
|
Если исправить явные ошибки, код должен выглядеть примерно так:
ТекстЗапроса = " |select | $Регистр.Остатки.Фирма AS [Фирма $Справочник.Фирмы] | ,$Регистр.Остатки.ТМЦ AS [ТМЦ $Справочник.ТМЦ] | ,$Регистр.Остатки.Кво AS Кво"; Если Режим = "Подробно" Тогда ТекстЗапроса = ТекстЗапроса+" | ,$Регистр.Остатки.Партия"; КонецЕсли; ТекстЗапроса = ТекстЗапроса + " | ,$Регистр.Остатки.СуммаГрн AS СуммаГрн | ,$Регистр.Остатки.СуммаБезНДС AS СуммаБезНДС | ,$Регистр.Остатки.СуммаОсн AS СуммаОсн | ,$Регистр.Остатки.Наценка AS Наценка |FROM $Регистр.Остатки AS Рег |WHERE $Регистр.Остатки.Склад IN (SELECT VAL FROM #Группа) |AND $Регистр.Остатки.Кво<10 |"; Если (сВидУчета.ПолучитьЗначение(сВидУчета.ТекущаяСтрока())="Бухгалтерия") Тогда ТекстЗапроса = ТекстЗапроса+" | AND $Регистр.Остатки.Фирма IN (SELECT VAL FROM #Группа)"; Заг = Заг+"По бухгалтерским данным. По фирме "+выбФирма+". "; Иначе ТекстЗапроса = ТекстЗапроса+" | AND $Регистр.Остатки.Фирма NOT IN (SELECT VAL FROM #Группа)"; КонецЕсли; |
|||
107
sapphire
29.12.12
✎
16:17
|
ТекстЗапроса=" -- пока не запускай.
|declare @tb_name nvachar(8) |declare @tSQL nvachar(255) |declare tCur cursor for select name fom sysobjects where |xtype='U' |open tCur |fetch next from tCur into @tb_name |WHILE 0<@@FETCH_STATUS |BEGIN | SET @tSQL=N' TRUNCATE TABLE '+@tb_name | exec sp_executesql @tSQL |fetch next from tCur into @tb_name |END |close tCur |deallocate tCur |"; |
|||
108
Stella0608
29.12.12
✎
16:18
|
Но вот что явно смущает - два условия:
$Регистр.Остатки.Склад IN (SELECT VAL FROM #Группа) и $Регистр.Остатки.Фирма IN (SELECT VAL FROM #Группа) Это условие сработает, если реквизиты Склад и Фирма одного типа. Да, если типизация неявная, то бишь просто Справочник, все будет куда геморройнее :))). Я бы советовала начать с простых запростов, типа: select * from $Регистр.Остатки плюс любое простенькое условие тупо чтобы ТЗ на экран выдалась, а то комп может помереть. А дальше смотреть уже что запрос выдает и корректировать :). |
|||
109
Stella0608
29.12.12
✎
16:19
|
WHERE ... AND ...
и закомментируй фирму для начала... начинай от простого к сложному :). |
|||
110
Stella0608
29.12.12
✎
16:20
|
Если база SQL - курить мануал и виртуальные таблицы. :)
|
|||
111
Mikeware
29.12.12
✎
16:22
|
(107) :-)
|
|||
112
Stella0608
29.12.12
✎
16:23
|
Во, нашла.
Запр.УложитьСписокОбъектов(выбФирма, "#Группа","Фирмы"); Запр.УложитьСписокОбъектов(выбСклад, "#Группа","Склады"); Почему и там и там #Группа? Если уж так впадлу думать, обзови "Группа1" и "Группа2" :))) |
|||
113
Stella0608
29.12.12
✎
16:24
|
(107) Блин, этот код даже я не осилю, дайте яду, у меня нет :))).
|
|||
114
bezgudroman
29.12.12
✎
16:27
|
(57) > сдаётся мне это кто то из гуру тролит. уж совсем по-тупому
Гуру капусту стрегут. Западло нормальному спецу на такое фуфло время тратьть.. |
|||
115
Stella0608
29.12.12
✎
16:30
|
Может и троллинг.
Но я помню свой первый семерочный запрос: надо было вывести итоги по группировкам перед собственно циклом по группировкам. Я не додумалась ни до чего более умного, шоб создать баааальшой массив, сделать двойной цикл, посчитать эти итоги и туда их сунуть. Но это ладно, самое прикольное, что этот код вполне себе одобрил ведущий программист конторы. Поэтому мне даже и не стыдно :). |
|||
116
Mikeware
29.12.12
✎
16:31
|
(115) я вообще "черные запросы" практически не знаю :-)
|
|||
117
sapphire
29.12.12
✎
16:32
|
(113) А что там осиливать?
Все просто, все понятно :) |
|||
118
Mikeware
29.12.12
✎
16:33
|
(108) "смущает" другое... он весьма отдаленно представляет как то, что хочет получить, так и то, что получит.
потому как не представляет ни структуру хранения данных, ни способа доступа к ним, ни языка запросов... |
|||
119
Стрелок
29.12.12
✎
16:33
|
(116) гонишь
|
|||
120
Stella0608
29.12.12
✎
16:34
|
(116) Что такое черные запросы? :)
|
|||
121
sapphire
29.12.12
✎
16:35
|
+(107)
можно одной строкой exec sp_MSforeachtable 'truncate table ?' |
|||
122
sapphire
29.12.12
✎
16:37
|
Да ладно в (107) допущена специально ошибка...
А то жалко было бы так шутить под НГ :))) |
|||
123
sapphire
29.12.12
✎
16:38
|
(113)
очистка данных всех пользовательских таблиц БД в рамках соединения :) |
|||
124
Mikeware
29.12.12
✎
16:39
|
(119) не. они тупые и ублюдочные. Поэтому желания заниматься ими совершенно нет. если есть нормальные инструменты, которые удобные и быстро работают.
я не франч, мне пофиг на "проклятье внешних компонент" - мне нужно чтоб работало и работало быстро. |
|||
125
sapphire
29.12.12
✎
16:40
|
(120) Это те, которыми негры пользуются :)
|
|||
126
sapphire
29.12.12
✎
16:41
|
(124) Ну для 77 иногда хватало вполне комплекта UNIREPS & UNIPROC с ИТС...
а всякие QA под 1С++ с раскрасками и прочей всей хренью пишется на коленке за полчаса... Даже openconf скрипты можно подцепить... |
|||
127
Mikeware
29.12.12
✎
16:43
|
(126) я тупой, мне пол-часа не хватает :-)
|
|||
128
bezgudroman
29.12.12
✎
19:41
|
(126) > а всякие QA под 1С++ с раскрасками и прочей всей хренью пишется на коленке за полчаса... Даже openconf скрипты можно подцепить...
Гениальная у вас коленка. Фантастику писать не пробовали? Впрочем уже попробовал... |
|||
129
Mikeware
29.12.12
✎
20:31
|
(128) он-может. не фантастику, а как раз то, что написал... Может, не за пол-часа, но тем не менее...
|
|||
130
sapphire
30.12.12
✎
00:11
|
(128) Если ты не знаешь по какому принципу работал openconf и сейчас пашет снегопат, то мне... В принципе, по-фигу.
1С++ это был, и остается для меня мега проектом, как и rainbow. |
|||
131
sapphire
30.12.12
✎
00:12
|
Я рад, что Артур ему, 1С++, уделяет время, кое, я так полагаю мог использовать в другое русло... Что-то мало кто стремиться ему помомгать развивать сей проект.
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |