|
v7: Снова пришлось юзать прямые запросы... | ☑ | ||
---|---|---|---|---|
0
al_zzz
23.11.17
✎
12:29
|
Появилась у меня задачка переносить данные из 1С7.7 в 1С8. А я к клюшкам не прикасался уже лет 10. Как семерошными запросами пользоваться - уже не помню, так как юзал, в основном прямые запросы 1С++(объект ODBCRecordset) для скульных баз.
Для них тогда была(да и сейчас есть) приличная документация: http://script-coding.com/Direct_queries.html Ею я и пользовался во всю. А тут база дбф-ная. Поискал - можно попробовать использовать Sqlite, нашел публикацию на нимфостарте, консолька там. Проверил на простеньких запросах - всё работает. Но такие вещи как получение периодических реквизитов, получение среза остатков не получается разобраться как сделать, а время уже поджимает. Поделитесь, плиз, примерами для Sqlite этих вещей, коллеги, кто богат. |
|||
1
Ёпрст
23.11.17
✎
12:30
|
||||
2
Ёпрст
23.11.17
✎
12:34
|
пример с периодикой
Процедура Сформировать() ТекстЗапроса=" |Select | Док.Номенклатура [Номенклатура :Справочник.Номенклатура] | ,Док.Количество Количество | ,( | select | Периодика.value | from __1S_Const Периодика | inner join [Справочник.Цены] as Цены on Цены.parentext = Док.Номенклатура and $Цены.ТипЦен = :ТипЦен | where Периодика.objid = Цены.id and Периодика.id = :ИсторияРеквизита.Цены.Цена | and ((Периодика.date < Жур.date) OR (Периодика.date = Жур.date)) | order by Периодика.date desc | limit 1 | | ) Цена |From [ДокументСтроки.ПоступлениеТМЦ] Док |inner join | [Журнал] Жур ON Док.iddoc = Жур.iddoc and Жур.date between :НачДата and:КонДата |"; Попытка база = СоздатьОбъект("SQLiteBase"); Исключение ЗагрузитьВнешнююКомпоненту("1sqlite.dll"); база = СоздатьОбъект("SQLiteBase"); КонецПопытки; // Откроем пустую базу данных в памяти база.Открыть(":memory:"); запрос = база.НовыйЗапрос(); Запрос.Подставлять("ТипЦен",ТипЦен); Запрос.Подставлять("НачДата",НачДата); Запрос.Подставлять("КонДата",КонДата); ВремяНачалоЗапроса=_GetPerformanceCounter(); ТЗ = запрос.ВыполнитьЗапрос(ТекстЗапроса); Сообщить("время запроса: "+(_GetPerformanceCounter()-ВремяНачалоЗапроса)); ТЗ.ВыбратьСтроку(); КонецПроцедуры |
|||
3
al_zzz
23.11.17
✎
12:40
|
(1) Спасибо!
А есть ещё пример с фильтром по списку? |
|||
4
Ёпрст
23.11.17
✎
12:48
|
ну, если используется типомой МФ (множественный фильтр на форме):
НомСтроки = 0; НомКолонки = 0; // Сначала проверим, есть ли множественный фильтр по номенклатуре. Если ТаблицаМФ.НайтиЗначение("Номенклатура", НомСтроки, НомКолонки) = 1 Тогда Если ТаблицаМФ.ПолучитьЗначение(НомСтроки, "ФлВкл") = 2 Тогда Список = СоздатьОбъект("СписокЗначений"); ТаблицаМФ.ПолучитьЗначение(НомСтроки,"СписокЭлементов").Выгрузить(Список); база.УложитьОбъекты(Список,"ВыбНоменклатура",0,"Номенклатура"); ТекстЗапроса=ТекстЗапроса+" | Where ПродажиУ.Номенклатура "+?(ТаблицаМФ.ПолучитьЗначение(НомСтроки,"ТипМФ")=1,""," NOT")+" IN (SELECT val FROM ВыбНоменклатура)"; КонецЕсли; КонецЕсли; |
|||
5
Ёпрст
23.11.17
✎
12:50
|
смысл, надеюсь понятен ?
грубо говоря, в тексте запроса: Where ПродажиУ.Номенклатура IN (SELECT val FROM ВыбНоменклатура) + укладка списка значений во временную ВыбНоменклатура база.УложитьОбъекты(Список,"ВыбНоменклатура",0,"Номенклатура"); |
|||
6
Ёпрст
23.11.17
✎
12:50
|
на счет синтаксиса УложитьОбъекты смотри справку от 1sqlite
в doc.chm |
|||
7
Базис
naïve
23.11.17
✎
12:51
|
В SQL перевести не предлагать?
|
|||
8
Ёпрст
23.11.17
✎
12:51
|
+ в 1sqlite можно укладывать таблицу значений во временную, тоже очень удобно.
|
|||
9
al_zzz
23.11.17
✎
12:55
|
(7) Нет, так как после переноса клиент будет продолжать вести основной учет в 77, а между этой ус и розницей будет работать обмен.
|
|||
10
ManyakRus
23.11.17
✎
15:30
|
надо подключить класс "ПрямойЗапрос"
у него текст запроса одинаковый для DBF, SQL, SQLLite почти такой же как 1С++ |
|||
11
al_zzz
27.11.17
✎
08:40
|
Напомните ещё, пожалуйста, как выбрать первые н записей в sqlite(в t-sql я пользовался top n), но тут так ругается.
|
|||
12
Ёпрст
27.11.17
✎
09:59
|
(11) в примере же есть - limit 1
|
|||
13
al_zzz
27.11.17
✎
10:11
|
(12) Точно! Туплю. Спасибо!
|
|||
14
al_zzz
13.12.17
✎
11:13
|
Подскажите ещё, пожалуйста, как мне получить максимальную запись цены из регистра остатков? Вот такая структура регистра: http://snap.ashampoo.com/KGorvkwA
Вот такой запрос я составил: ТекстЗапроса = "Select |РозничныеЦены.Номенклатура As [Номенклатура :Справочник.Номенклатура], | ""Розничная"" As ВидЦены, |РозничныеЦены.НоваяЦена As Цена |From [Регистр_РозничныеЦены] As РозничныеЦены | Inner Join [Журнал] As Журнал On Журнал.IdDoc = РозничныеЦены.IdDoc | Inner Join (Select | РозничныеЦены.Номенклатура As Ном_ИД, | Max(Журнал.idx_DATE_TIME_IDDOC) As Время |From [Регистр_РозничныеЦены] As РозничныеЦены | Inner Join [Журнал] As Журнал On Журнал.IdDoc = РозничныеЦены.IdDoc | Where РозничныеЦены.Номенклатура in (Select НомТемп.val From НомТемп As НомТемп) | Group by РозничныеЦены.Номенклатура) As Sub On Sub.Ном_ИД = РозничныеЦены.Номенклатура and Журнал.idx_DATE_TIME_IDDOC = Sub.Время | Where РозничныеЦены.Номенклатура in (Select НомТемп.val From НомТемп As НомТемп) | Order by РозничныеЦены.Номенклатура"; Но по факту он мне возвращает не самую позднюю запись по номенклатуре. ЧЯДНТ? |
|||
15
al_zzz
13.12.17
✎
12:05
|
Хелп! Горю!
|
|||
16
al_zzz
13.12.17
✎
13:34
|
Короче, я не понял, что произошло, но этот запрос стал выдавать верные результаты(как, собственно, и я и ожидал от него). Ещё есть такое замечание, или, скорее, вопрос:
Если мне надо взять актуальный срез остатков по регистру остатков, то я использую просто Итоги_* с отбором по периоду где в качестве периода передаю начало месяца(это я на практике выяснил): .................. |FROM | РегистрИтоги_ОстаткиТоваров as Итоги //Inner Join НомТемп As НомТемп On НомТемп.val = Итоги.Товар |WHERE | Итоги.Товар in (Select НомТемп.val From НомТемп As НомТемп) |and Итоги.period = :ПредПериод .................................... запрос = база.НовыйЗапрос(); мд = СоздатьОбъект("MetaDataWork"); НачПериод = мд.ПолучитьНачПериода(ТекущаяДата());//начало периода Запрос.Подставлять("ПредПериод",НачПериод); А в примере из (1) надо к моему срезу прибавить ещё движения за период, чтоб получить актуальный остаток. Почему так? |
|||
17
Ёпрст
13.12.17
✎
18:35
|
(16) промежуточные итоги хранятся на дату начала периодичности итогов (если периодичность месяц - на начало месяца, при другой периодичности - на начало этой периодичности)
Соответственно, если нужны итоги на ТА - просто берм итог на последнюю дату периодичности итогов, если остаток за произвольную дату - берем предыдущий итог от начала периодичности + прибавляем оборот с таблички движений. Усё. |
|||
18
Ёпрст
13.12.17
✎
18:35
|
(14) эта хрень вообще не должна работать
|
|||
19
Ёпрст
13.12.17
✎
18:37
|
ну и в регистре воткни галку - быстрая обработка движений и из запроса выкини потом соединение с 1sjourn за ненадобностью.
|
|||
20
al_zzz
14.12.17
✎
09:31
|
(18) Почему не должна? Там, получается, в подзапросе выбирается максимально поздняя дата записи для номенклатуры, а потом берется вся запись для неё по этой дате. Max(Журнал.idx_DATE_TIME_IDDOC) - вот это у меня вызывает сомнения - будет ли так находиться максимальное дата-время?
Галку втыкать не хочу, так как затормозится запись туда, потому . |
|||
21
al_zzz
14.12.17
✎
09:33
|
(17) Спасибо!
|
|||
22
Ёпрст
14.12.17
✎
09:47
|
(20) на счет "затормозиться" запись - ты это не заметишь, это микросекунды
|
|||
23
Ёпрст
14.12.17
✎
09:48
|
единственное, будет лишнее поле в табличке движений регистра, не надо будет соединение с журналом.Даже штатные чорные запросы будут быстрее выполняться.
|
|||
24
al_zzz
14.12.17
✎
11:06
|
(23) "Лошадь не моя" - не хочу, чтоб потом "гений-программист", который всё это хозяйство обслуживает, тыкал меня носом на то, что запись замедлилась.
|
|||
25
Ёпрст
14.12.17
✎
11:25
|
(24) она не замедлится
|
|||
26
Ёпрст
14.12.17
✎
11:25
|
сравни на копии
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |