![]() |
|
v7: 1C++ Прямой запрос помогите с решением. | ☑ | ||
---|---|---|---|---|
0
AlexeyMK
26.05.12
✎
12:35
|
Добрый день. Есть запрос:
"//{{ЗАПРОС(ПоДокументам) |Период с '01.01.1980' по ДатаКонца; | |Контрагент = Регистр.Покупатели.Договор.Владелец, | Регистр.Поставщики.Договор.Владелец; | |КодОперации = Регистр.Покупатели.КодОперации, | Регистр.Поставщики.КодОперации; | |ДолгВал = Регистр.Покупатели.СуммаРуб, | Регистр.Поставщики.СуммаРуб; | |Группировка Контрагент без групп; | |Группировка Документ; | |Функция Расход = Приход(ДолгВал) Когда (КодОперации в СписокОперДебет); | |Функция Приход = Расход(ДолгВал) Когда (КодОперации в СписокОперКредит); | |Функция ИзначальнаяСумма = Расход(ДолгВал) Когда (КодОперации в СписокОперКредит); | |"//}}ЗАПРОС ; Помогите пожалуйста переложить его на прямой с помощью 1C++. Всю голову сломал уже. |
|||
2
МихаилМ
26.05.12
✎
12:39
|
если б сломали, то привелибы код.
а так Вы просите написать за Вас |
|||
3
МастерВопросов
26.05.12
✎
13:08
|
ну самое простое что приходит на ум:
Select <список полей через запятую>, <три CASE when <условие на КодОперации> и т.д.> From <имя виртуальной таблицы оборотов Регистра "Покупатели"> Group by <Список полей группировки> |
|||
4
viktor_vv
26.05.12
✎
14:36
|
(3) С виртуальной не получится. В виртуальной нету Реквизитов, а КодОперации это реквизит, по-моему. Во From Полное соединение реальных таблиц движений двух регистров, плюс левое соединение со справочником договора. Или Объединить Все для таблиц движений регистров, может быстрее будет.
|
|||
5
МастерВопросов
26.05.12
✎
16:19
|
(4) да да, ты прав. Еще я просмотрел что там два регистра Поставщики и Покупатели.
|
|||
6
AlexeyMK
26.05.12
✎
16:36
|
Я пытаюсь постепенно написать запрос. Вот что есть сейчас. Но поле Док почему то пустое:
Процедура ИнициализациSQL() ОлеДБ = СоздатьОбъект("OLEDBData"); Соединение = "Provider=VFPOLEDB.1;Data Source=" + КаталогИБ() + ";Mode=ReadWrite;Collating Sequence=MACHINE"; Рез = ОлеДБ.Соединение(Соединение); ЗапросSQL = ОлеДБ.СоздатьКоманду(); ЗапросSQL.Выполнить("EXECSCRIPT('SET ANSI OFF')"); // Устанавливаем время ожидания захвата таблиц , если во время выполнения запроса кто то проводит документы // Очень полезная функция - аналогична времени ожидания в 1С ЗапросSQL.Выполнить("EXECSCRIPT('SET REPROCESS TO 60 SECONDS')"); // Убираем буфепизацию, чтобы данные возвращаемые запросам всегда были актуальны ЗапросSQL.Выполнить("EXECSCRIPT('SET REFRESH TO 0,-1')"); ЗапросSQL.Выполнить("Exec('SET TABLEVALIDATE TO 0')");// Отключили блокировки КонецПроцедуры ... ИнициализациSQL() ТекстЗапроса = " |SELECT | tmp.Контрагент as [Контрагент $Справочник.Контрагенты] | ,tmp.Док AS [Документ $Документ] | ,SUM(tmp.СуммаРуб) AS Приход | ,SUM(tmp.СуммаРуб1) AS Расход | |FROM ( | | SELECT | Дог1.parentext AS Контрагент | ,Рег.IDDoc as Док | ,Жур.IDDocDef as Док_вид | ,$Рег.СуммаРуб AS СуммаРуб | ,$Рег.СуммаРуб AS СуммаРуб1 | FROM | $Регистр.Покупатели AS Рег | | LEFT JOIN $Справочник.Договоры as Дог1 on Дог1.id = $Рег.Договор | | INNER JOIN 1sjourn AS Жур ON Жур.Iddoc = Рег.IDDoc AND | DTOS(Жур .date)+Жур .time+Жур .iddoc BETWEEN | DTOS(:НачДата~~)+' '+' ' | And DTOS(:КонДата~~)+'ZZZZZZ'+'ZZZZZZZZZ' | | UNION ALL | | SELECT | Дог2.parentext AS Контрагент | ,Рег1.IDDoc as Док | ,Жур.IDDocDef as Док_вид | ,$Рег1.СуммаРуб AS СуммаРуб | ,$Рег1.СуммаРуб AS СуммаРуб1 | FROM | $Регистр.Поставщики AS Рег1 | | LEFT JOIN $Справочник.Договоры as Дог2 on Дог2.id = $Рег1.Договор | | INNER JOIN 1sjourn AS Жур ON Жур.Iddoc = Рег1.IDDoc AND | DTOS(Жур .date)+Жур .time+Жур .iddoc BETWEEN | DTOS(:НачДата~~)+' '+' ' | And DTOS(:КонДата~~)+'ZZZZZZ'+'ZZZZZZZZZ') as tmp | | |GROUP BY tmp.Контрагент,tmp.Док |"; ЗапросSQL.УстановитьТекстовыйПараметр("НачДата", Дата('01.01.1980')); ЗапросSQL.УстановитьТекстовыйПараметр("КонДата", ДатаКонца); ТЗ = ЗапросSQL.ВыполнитьИнструкцию(ТекстЗапроса); ТЗ.ВыбратьСтроку(); |
|||
7
МастерВопросов
26.05.12
✎
17:01
|
не уверен, но попробуй так "INNER JOIN 1sjourn AS Жур ON Жур.Iddoc = substring(Рег1.IDDoc,5,9)"
|
|||
8
МастерВопросов
26.05.12
✎
17:04
|
(6) и у тебе не совсем верно запрос составлен
либо выноси условие "DTOS(Жур .date)+Жур .time+Жур .iddoc BETWEEN | DTOS(:НачДата~~)+' '+' ' | And DTOS(:КонДата~~)" в "where" либо "LEFT JOIN $Справочник.Договоры" замени на "INNER JOIN" |
|||
9
leshikkam
26.05.12
✎
17:05
|
А не проще класс ПрямойЗапрос использовать с 1sqlite - там удобней писать.
|
|||
10
МастерВопросов
26.05.12
✎
17:15
|
(8) нет, блин, в (6) всё верно. Извини.
Так у тебя, вообще, запрос записей не возвращает, или только поле "Документ" пустое? |
|||
11
AlexeyMK
26.05.12
✎
17:18
|
>МастерВопросов
Запрос возвращает записи, но поле Док пусто, идут только контрагенты. причем если я убираю JOIN со справочником Договоры, все нормально. |
|||
12
МастерВопросов
26.05.12
✎
17:19
|
||||
13
МастерВопросов
26.05.12
✎
17:24
|
(11) ну в порядке бреда попробуй убрать типизацию [Документ $Документ] и так посмотри будут ссылки в этом поле?
|
|||
14
AlexeyMK
26.05.12
✎
17:27
|
>МастерВопросов(13)
Щас проверю |
|||
15
AlexeyMK
26.05.12
✎
17:44
|
Хм... Вот так вот этот этап похоже "взлетел":
ТекстЗапроса = " | | SELECT | Дог1.parentext AS [Контрагент $Справочник.Контрагенты] | ,Рег.IDDoc as [Док $Документ] | ,Жур.IDDocDef as Док_вид | ,$Рег.СуммаРуб AS СуммаРуб | ,$Рег.СуммаРуб AS СуммаРуб1 | FROM | $Регистр.Покупатели AS Рег | | LEFT JOIN $Справочник.Договоры as Дог1 on Дог1.id = $Рег.Договор | | INNER JOIN 1sjourn AS Жур ON Жур.Iddoc = Рег.IDDoc AND | DTOS(Жур .date)+Жур .time+Жур .iddoc BETWEEN | DTOS(:НачДата~~)+' '+' ' | And DTOS(:КонДата~~)+'ZZZZZZ'+'ZZZZZZZZZ' | | UNION ALL | | SELECT | Дог2.parentext AS [Контрагент $Справочник.Контрагенты] | ,Рег1.IDDoc as [Док $Документ] | ,Жур.IDDocDef as Док_вид | ,$Рег1.СуммаРуб AS СуммаРуб | ,$Рег1.СуммаРуб AS СуммаРуб1 | FROM | $Регистр.Поставщики AS Рег1 | | LEFT JOIN $Справочник.Договоры as Дог2 on Дог2.id = $Рег1.Договор | | INNER JOIN 1sjourn AS Жур ON Жур.Iddoc = Рег1.IDDoc AND | DTOS(Жур .date)+Жур .time+Жур .iddoc BETWEEN | DTOS(:НачДата~~)+' '+' ' | And DTOS(:КонДата~~)+'ZZZZZZ'+'ZZZZZZZZZ' | |"; Тогда следующий вопрос, если уже помощь близко: Вот эта конструкция как ты сказал, может реализоваться с помощью CASE-ов: |Функция Расход = Приход(ДолгВал) Когда (КодОперации в СписокОперДебет); |Функция Приход = Расход(ДолгВал) Когда (КодОперации в СписокОперКредит); Т.е правильно я понимаю, что вот как нибудь так: | SELECT | Дог1.parentext AS [Контрагент $Справочник.Контрагенты] | ,Рег.IDDoc as [Док $Документ] | ,Жур.IDDocDef as Док_вид | ,(CASE WHEN Рег.КодОперации IN(стрУсловиеДебет) THEN Рег.СуммаРуб AS Приход) | ,(CASE WHEN Рег.КодОперации IN(стрУсловиеКредит) THEN Рег.СуммаРуб AS Расход) Или как нибудь по другому? Не пойму. В обычном запросе, список операций дебет и список операций кредит разные, соответственно у меня в разные суммы попадают расходы и приходы. А здесь как? |
|||
16
viktor_vv
26.05.12
✎
17:49
|
У таблицы дивжений регистра остатков есть поле debkred, признак вида движения (приход расход). Кажись 0 это приход, 1 это расход.
|
|||
17
viktor_vv
26.05.12
✎
17:52
|
И ты бы таки под ДБФ sqlite использовал, там поудобнее будет и УложитьСписокОбъектов() работать будет для условий. А то тут еще и проблемы будут при монопольном доступе.
|
|||
18
AlexeyMK
26.05.12
✎
17:57
|
>viktor_vv
Сейчас попробую про sqlite почитать. Насколько я понял это внешняя библиотека, сам движок с DBF не надо на SQL переводить? |
|||
19
viktor_vv
26.05.12
✎
18:02
|
(18) Не, переводить никуда ненадо. А для получения суммы что такое надо будет.
Sum($РегОст.чСумма * (1 - РегОст.debkred)) as СуммаПриход Sum($РегОст.чСумма * РегОст.debkred) as СуммаРасход |
|||
20
viktor_vv
26.05.12
✎
18:07
|
Вот тут смотри http://snegopat.ru/1sqlite/index .
|
|||
21
AlexeyMK
26.05.12
✎
18:18
|
(20) Спасибо.
|
|||
22
AlexeyMK
26.05.12
✎
19:34
|
Просьба ответить на еще несколько вопросов:
В запросе есть обращение к реквизиту документа - |Торговый = Регистр.Покупатели.ТекущийДокумент.Торговый, | Регистр.Поставщики.ТекущийДокумент.Торговый; в SQL обращение к документу происходит через IDDoc и IDDocDef. Как добраться до реквизита документа? И еще ответ на предыдущий вопрос, как правильно выбрать приходы и расходы по КодуОпераций? |
|||
23
viktor_vv
26.05.12
✎
19:44
|
Судя по тексту Торговый это общий реквизи ?
|
|||
24
AlexeyMK
26.05.12
✎
19:50
|
(23) да, это общий реквизит документа.
|
|||
25
SnarkHunter
26.05.12
✎
20:02
|
(24)Общий реквизит документ с отбором или нет?
|
|||
26
AlexeyMK
26.05.12
✎
20:08
|
(25) да с отбором.
|
|||
27
SnarkHunter
26.05.12
✎
20:10
|
Тогда это _1sjourn.$ОбщийРеквизит.Торговый
|
|||
28
AlexeyMK
26.05.12
✎
20:26
|
(27) Точно!
|
|||
29
ЧеловекДуши
28.05.12
✎
13:05
|
>>> 01.01.1980
Не продуктивный запрос, через пару лет отомрет даже на SQL версии :) ...Что за отчет хоть делаешь, что нужна расшифровка по документно? |
|||
30
Ёпрст
гуру
28.05.12
✎
13:42
|
(15) в дбф свой "case", там немного другой синтаксис + icase это
(22) воткнуть условие на код в расчет функции sum вестимо |
|||
31
AlexeyMK
28.05.12
✎
20:56
|
(29) Нарушен партионный учет, попытка формирования отчета по ПДЗ.
(30) Да, спасибо я уже понял. Использовал ICASE(INLIST(val,1,2,3),true,false) |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |