Имя: Пароль:
1C
1C 7.7
v7: Вопрос по УРБД
,
0 kloptula
 
29.12.11
16:51
Понимаю, что тема уже обсуждалась сто раз, но я не нашел ответа на свой вопрос.

Хотим организовать схему обмена "снежинка". Обмены идут в разделенном режиме. Можно ли править 1supdts.dbf прямым запросом через ADO. Какие подводные камни могут возникнуть?
1 Ёпрст
 
29.12.11
16:58
Если база файловая, то не взлетит.
2 kloptula
 
29.12.11
19:44
А почему не взлетит? Там же при удалении строки из dbf запись только помечается как удаленная, структура не должна по идее рушиться?
3 Ёпрст
 
29.12.11
19:47
(2) ну, при делете да, а вот при инсерте не взлетит - индекс будет другой.
А так, oledb в рукти и вперёд.
4 kloptula
 
29.12.11
19:53
А чисто технически компонента как работает?

1. Вот я отправил пакет с измененными данными в периферию.
2. Периферия получила пакет и отправила мне подтверждение, что получила.
3. Центральная база удалила записи из 1SUPDTS и ...

Она сжимает его (физически записи удаляются из файла) или помечает записи как удаленные?
5 ДенисЧ
 
29.12.11
19:54
(4) Она говорит драйверу delete. А что он там делает с данными, это уже не забота урбд
6 kloptula
 
29.12.11
20:10
Спасибо, буду пробовать на практике
7 Ёпрст
 
29.12.11
20:12
(4) метит записи на удаление, новые записи пишутся в начале, на место "удаленных".
8 Ёпрст
 
29.12.11
20:13
потом уже,мна "свободное" место, т.е в конец.
9 fisher
 
29.12.11
20:13
Переведи на SQL.
Это будет намного проще, чем с файловой колупаться.
Плюс попутные профиты...
10 fisher
 
29.12.11
20:15
Там хошь триггер на _1supdts вешай, хошь хранимку правь, которая вставку строк туда делает.
11 kloptula
 
29.12.11
21:07
Контора полугосударственная, денег на SQL не дадут. Надо было вообще 8-ку внедрять, денег не выделили. Пришлось на семерке извращаться со всеми вытекающими
12 Mikeware
 
30.12.11
07:16
(11) попробуй на SQLite перейти...
13 kloptula
 
30.12.11
11:41
А в чем плюс sqlite перед тем же ADO?
14 Mikeware
 
30.12.11
12:03
(13) в индексах
15 kloptula
 
30.12.11
12:18
(14) То есть он может работать с индексами 1С и можно ворочать dbf как душе угодно, индексы обновятся автоматически, без переиндексации
16 Mikeware
 
30.12.11
12:20
(15) Нет. Ну прочитай ты уже описалово...
17 fisher
 
30.12.11
13:10
Насколько я понял, на самом деле речь о компоненте 1sqlite.
Только челу ведь еще и редактировать надо. 1sqlite разве позволяет?
18 Mikeware
 
30.12.11
16:09
(17) а разве нет? Ты считаешь, что база на 1sqlite работает в режиме  read only? :-)
19 fisher
 
30.12.11
16:19
(18) Ты сам-то с ней работал? Насколько я понял из описалова, база sqllite используется компонентой только для быстрой работы с ТЗ и иже с ними (работа с быстрыми временными структурами). А база как была в dbf, так и остается. Просто можно с ней работать опять-таки через движок sqllite (на чтение).
Буду безмерно рад ошибиться.
20 Mikeware
 
30.12.11
16:34
(19) Не "быстрой работы с ТЗ", а работой с виртуальными таблицами...
Сам не оаботал. Нет у меня мелких баз, к которым это можноприменить...
21 пипец
 
30.12.11
16:39
в урбд не используй русских букв в названии баз данных
22 fisher
 
30.12.11
16:42
(20) Я так и не понял, так можно с помощью 1sqlite модифицировать данные 1С или нет? Или ты просто выдавал желаемое за действительное?
23 kloptula
 
06.01.12
20:59
Вообщем выкладываю на суд общественности что получилось.

// Стр: исходная строка, Длина: длина строки на выходе, Символ: символ дополнения, Порядок: 1 - в начало строки, 2 - в конец строки
Функция ДополнитьСтроку(Стр, Длина, Символ, Порядок)
   
   Пока СтрДлина(Стр) < Длина Цикл
       Если Порядок = 1 Тогда
           Стр = Символ+Стр;
       КонецЕсли;          
       Если Порядок = 2 Тогда
           Стр = Стр+Символ;
       КонецЕсли;
   КонецЦикла;
       
   Возврат Стр;
   
КонецФункции

Функция СтрокаСимв(Символ, Колво)
   
   i = 0;
   Стр = "";
   Для i = 1 По Колво Цикл
       Стр = Стр + Символ;
   КонецЦикла;        
   
   Возврат Стр;
   
КонецФункции    // СтрокаСимв

Функция ПолучитьОбъект(ТипStr, ОбStr, IB)    
   
   Список = СоздатьОбъект("СписокЗначений");
   Список.ДобавитьЗначение("B");
   Список.ДобавитьЗначение("0");
   Список.ДобавитьЗначение("0");
   Список.ДобавитьЗначение(""+_StrToId(ТипStr)+"");
   Список.ДобавитьЗначение("0");
   Список.ДобавитьЗначение("0");
   Список.ДобавитьЗначение(""+СтрокаСимв(" ",10-СтрДлина(_StrToId(ОбStr)))+_StrToId(ОбStr)+IB+"");
   Зн = ЗначениеИзСтрокиВнутр("{"+Список.ВСтрокуСРазделителями()+"}");
   Если ТипЗначенияСтр(Зн)="Справочник" Тогда  
       Возврат Зн;
   Иначе
       Список.УдалитьВсе();
       Список.ДобавитьЗначение("O");
       Список.ДобавитьЗначение("0");
       Список.ДобавитьЗначение("0");
       Список.ДобавитьЗначение(""+_StrToId(ТипStr)+"");
       Список.ДобавитьЗначение("0");
       Список.ДобавитьЗначение("0");
       Список.ДобавитьЗначение(""+СтрокаСимв(" ",10-СтрДлина(_StrToId(ОбStr)))+_StrToId(ОбStr)+IB+"");
       Зн = ЗначениеИзСтрокиВнутр("{"+Список.ВСтрокуСРазделителями()+"}");    
       Возврат Зн;
   КонецЕсли;
   
КонецФункции

//*******************************************
Процедура ЧисткаУРБД()

   //РАБОТА С ФАЙЛАМИ DBF ЧЕРЕЗ ADO    
   Путь = КаталогИБ(); //Путь к папке с файлами DBF
   
   ТаблицаЗаписей = СоздатьОбъект("ТаблицаЗначений");
   ТаблицаЗаписей.НоваяКолонка("DBSIGN");
   ТаблицаЗаписей.НоваяКолонка("TYPEID");
   ТаблицаЗаписей.НоваяКолонка("OBJID");
             
   Соединение = СоздатьОбъект("ADODB.Connection");
   Соединение.Open("Provider=Microsoft.Jet.OLEDB.4.0;" +
               "Data Source=" + Путь + ";" +
               "Extended Properties=""DBASE IV;"";");          

   НаборЗаписей = Соединение.Execute("SELECT * FROM 1SUPDTS");
   Пока НаборЗаписей.EOF = 0 Цикл //Цикл по записям DBF      
       DBSIGN = НаборЗаписей.Fields("DBSIGN").Value;
       TYPEID = НаборЗаписей.Fields("TYPEID").Value;
       OBJID = ДополнитьСтроку(НаборЗаписей.Fields("OBJID").Value, НаборЗаписей.Fields("OBJID").DefinedSize, " ", 2);
                   
       // Получаем объект базы данных
       Об = ПолучитьОбъект(СокрЛП(TYPEID), Лев(OBJID, 6), Прав(OBJID, 3));

       Попытка
           // Удалим лишние записи              
           Если Об.Вид() = "СчетФактураПолученный" Тогда
               Если Об.ДокОснование.Склад.Код <> ДополнитьСтроку(СокрЛП(DBSIGN), 5, "0", 1) Тогда
                   ТаблицаЗаписей.НоваяСтрока();                                    
                   ТаблицаЗаписей.DBSIGN = DBSIGN;
                   ТаблицаЗаписей.TYPEID = TYPEID;
                   ТаблицаЗаписей.OBJID = OBJID;
               КонецЕсли;            
           КонецЕсли;
                 
           Если глЕстьРеквизитШапки("Склад", Об.Вид()) = 1 Тогда
               Если Об.Склад.Код <> ДополнитьСтроку(СокрЛП(DBSIGN), 5, "0", 1) Тогда
                   ТаблицаЗаписей.НоваяСтрока();                                    
                   ТаблицаЗаписей.DBSIGN = DBSIGN;
                   ТаблицаЗаписей.TYPEID = TYPEID;
                   ТаблицаЗаписей.OBJID = OBJID;
               КонецЕсли;
           КонецЕсли;
       Исключение
       КонецПопытки;
       
       НаборЗаписей.MoveNext(); //Переходим к след. записи DBF
   КонецЦикла;  
   
   ТаблицаЗаписей.ВыбратьСтроки();
   Пока ТаблицаЗаписей.ПолучитьСтроку() = 1 Цикл  
       Соединение.Execute("DELETE FROM 1SUPDTS WHERE DBSIGN="""+ТаблицаЗаписей.DBSIGN+""""+" AND TYPEID="""+ТаблицаЗаписей.TYPEID+""""+" AND OBJID="""+ТаблицаЗаписей.OBJID+"""");
   КонецЦикла;

   Соединение.Close(); //Закрываем соединение
   Сообщить("Чистка прошла успешно!!!");            
             
КонецПроцедуры
24 kloptula
 
06.01.12
21:01
Может кто-нибудь посоветует, как сформировать запрос на удаление разом всех лишних записей из файла, а то приходится в цикле запросы слать на удаление
25 Дядя Васька
 
06.01.12
21:24
(22) нельзя
26 Дядя Васька
 
06.01.12
21:26
(24) = заменить на IN, ТЗ на списки значений
27 ЧеловекДуши
 
06.01.12
21:44
Денег нет, а на прогера есть :)
При этом прогер будет стоить куда больше :)
28 kloptula
 
06.01.12
22:09
(26)
DELETE FROM 1SUPDTS WHERE DBSIGN IN "+СписокЗаписейDBSIGN+" AND TYPEID IN "+СписокЗаписейTYPEID+" AND OBJID IN "+СписокЗаписейOBJID

Так как-то запрос выглядеть будет?
29 ДенисЧ
 
06.01.12
22:10
(28) не, фигово
30 kloptula
 
06.01.12
22:12
(29) Как лучше?
31 Дядя Васька
 
07.01.12
04:05
(30) Если мне склероз не изменяет идентификатор базы в ид объекта имеется, стало быть он уникален по всем базам, тип стало быть тоже не нужен. Достаточно просто:
DELETE FROM 1SUPDTS WHERE OBJID IN "+СписокЗаписейOBJID
32 Дядя Васька
 
07.01.12
04:12
+(31) DBSIGN судя по всему используется при подготовке файла выгрузки, дабы можно было быстро отобрать записи от конкретной базы, TYPEID соответственно при загрузке, когда отыскивают есть ли измененные записи по определенному объекту метаданных. Т.е. избыточная информация, используемая для ускорения работы. Вся она есть в OBJID.
33 ДенисЧ
 
07.01.12
07:30
(32) не угадал. objid - это короткий ид. А он может пересекаться по метаданным. Поэтому точно объект даёт только typeid+objid
34 Дядя Васька
 
07.01.12
14:36
(33) Эм... Согласен, типа нет в коротком. Есть ID и код базы. Но ID по базе не повторяется. Так что вполне себе уникально будет, просто не поймешь что за объект метаданных.
35 ДенисЧ
 
07.01.12
14:57
(34) ид в журнале и справочнике - запросто могут повторояться.
36 Дядя Васька
 
07.01.12
15:32
(35) Да нифига...
37 ДенисЧ
 
07.01.12
15:34
(36) да фига. сам наткнулся.
38 Дядя Васька
 
07.01.12
15:41
(37) Но как? Это же GUID и есть, ЗначениеВСтрокуВнутр() в конце строки его и возвращает. Чет ты путаешь. Понять что это по 6-ти символам невозможно, но повторов-то нет.
39 Дядя Васька
 
07.01.12
15:45
+(38) Не тот конечно что по международным правилам, в пределах базы.
40 Cthulhu
 
07.01.12
15:46
(38): Ид вида портит картинку.
41 ДенисЧ
 
07.01.12
15:52
(38) тема про 77!!!!!
42 Дядя Васька
 
07.01.12
16:02
(41) В (39) уточнил.
(40) Не портит, если не важно что именно это за элемент, и нужно только быть уверенным что нет другого с таким ID (основной который).
43 ДенисЧ
 
07.01.12
16:03
в _1supdts есть два поля: typeid и objid. Они являются уникальным ключом. По отдельности - не являются. Вот и все дела.
45 Дядя Васька
 
07.01.12
16:41
Убейте спамера в (44)
46 kloptula
 
07.01.12
16:47
Вообщем сделал по 2-м полям как в (43), все работает, запускаю на боевую базу, посмотрим, что получится. Спасибо всем за разъяснения.
47 Cthulhu
 
07.01.12
17:19
(46): слепи если не трудно обработочку с тудой-сюдой между ид-ами и объектами данных?
48 ДенисЧ
 
07.01.12
17:19
(47) какую обработочку???
Там на 1с++ 3 строки...
49 Cthulhu
 
07.01.12
17:29
(48): я не просил с ВК, есичо.
не вони "по правилу начальника", нет так нет.
50 kloptula
 
07.01.12
18:03
(47) Это зачем еще?
Компьютеры — это как велосипед. Только для нашего сознания. Стив Джобс