Имя: Пароль:
1C
1C 7.7
v7: УстБД1С() надо или нет?
0 monsterZE
 
26.10.12
11:43
есть внешняя СКЛ база, которая используется из 1с
Запрос.УстБД(ОДБЦ_ДБ);
бла-бла-бла
ОДБЦ_ДБ.Закрыть();
надо после этого делать УстБД1С() или нет?
---
прост переписал сейчас на живой.. пока проверить не могу =)
1 ЧеловекДуши
 
26.10.12
11:48
(0)Нет

Вот рабочая конструкция;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Проведен: 1 - отберать по проведенным,
//            0 - не учитывать (если ""БезУдаленых = 0"", то отбераются все документы)
//БезУдаленых:  1 - отбераются не помеченные на удаления,
//                2 - отбираются только помеченные на удаления, 0 - не учитывать
//Параметры "Проведен" и "БезУдаленых", при не нулевом значении, отрабатывают совместно по принципу "ИЛИ".
//
//Порядок: 0 - Сортровать по возрастанию, 1 - Сортировать по Убыванию.
//
//ВремяДатаТайм: 0 - Отбирать документ, как Дату и время (ИД документа не учитывается)... 1 - Учитывается еще и ИД документа
Функция глВыбратьПодчиненныеДокументы(ДатаНач,ДатаКон,Док,ТипДок="",Проведен=0,БезУдаленых=0,Порядок=0,ВремяДатаТайм=1) Экспорт
   Перем Рез;
   Перем ТЗЗапрос, СкульЗапрос;
   Перем СтрокаДляЗапроса, НомСимв, КолСимв, СтрокПоиск,СтрокПолуч;
   Перем МетаНомер, ЧтоЭто;
   
   //Для локального применения
   //глRecord1С = СоздатьОбъект("ODBCRecordSet");
   //глMeta1С = СоздатьОбъект("MetaDataWork");
   
   Если ТипЗначенияСтр(глRecord1С) <> "ODBCRecordSet" Тогда
       глRecord1С = 0;
       глRecord1С = СоздатьОбъект("ODBCRecordSet");
   КонецЕсли;
   
   Если ТипЗначенияСтр(глMeta1С) <> "MetaDataWork" Тогда
       глMeta1С = 0;
       глMeta1С = СоздатьОбъект("MetaDataWork");
   КонецЕсли;
   
   Рез = 0; //Ошибка в запросе!
   Если ТипЗначения(Док) <> 12 Тогда //12 - агрегатный тип данных 'Документ';
       Возврат Рез;
   ИначеЕсли ПустоеЗначение(Док) = 1 Тогда
       Рез = СоздатьОбъект("ТаблицаЗначений");
       Рез.НоваяКолонка("Док","Документ");
       Возврат Рез;
   КонецЕсли;
   
   Если глОтладкаSQL = 1 Тогда
       глRecord1С.Отладка(1);
   КонецЕсли;
   
   СкульЗапрос="
   |SELECT
   | dbo.sp_tohex(TabJ.IDDOCDEF,4)+TabJ.IDDOC [Док $Документ]
   |FROM
   | _1SCRDOC As TabRod(NOLOCK)
   |INNER JOIN
   | _1SJOURN As TabJ(NOLOCK) ON (TabRod.CHILDID = TabJ.IDDOC)
   |WHERE
   | TabRod.MDID = 0 -- только документы, без граф отбора
   | AND TabRod.PARENTVAL = '"+глMeta1С.ЗначениеВСамуюДлиннуюСтрокуБД(Док.ТекущийДокумент())+"'
   |";
   Если ПустоеЗначение(ДатаНач)=0 Тогда
       МетаНомер = "";
       Если ТипЗначения(ДатаНач) = 12 Тогда //Документ
           Если ВремяДатаТайм = 0 Тогда
               МетаНомер = ""+глMeta1С.ПолучитьДатуВремяИдДок(ДатаНач.ПолучитьПозицию());
           Иначе
               МетаНомер = ""+глMeta1С.ПолучитьДатуВремяИдДок(ДатаНач.ПолучитьПозицию())+глMeta1С.ЗначениеВСтрокуБД(ДатаНач.ТекущийДокумент());
           КонецЕсли;
       ИначеЕсли ТипЗначения(ДатаНач) = 3 Тогда //3 - тип данных Дата;
           МетаНомер = ""+глMeta1С.ПолучитьСтрИзДаты(ДатаНач);
       ИначеЕсли ПустоеЗначение(Дата(ДатаНач)) = 0 Тогда
           МетаНомер = ""+глMeta1С.ПолучитьСтрИзДаты(Дата(ДатаНач));
       КонецЕсли;
       Если ПустоеЗначение(МетаНомер) = 0 Тогда
             СкульЗапрос=СкульЗапрос+"
             |and TabJ.DATE_TIME_IDDOC>='"+МетаНомер+"'
           |";
       КонецЕсли;
   КонецЕсли;
   Если ПустоеЗначение(ДатаКон)=0 Тогда
       МетаНомер = "";
       Если ТипЗначения(ДатаКон) = 12 Тогда //Документ
           Если ВремяДатаТайм = 0 Тогда
               МетаНомер = ""+глMeta1С.ПолучитьДатуВремяИдДок(ДатаКон.ПолучитьПозицию())+"Z";
           Иначе
               МетаНомер = ""+глMeta1С.ПолучитьДатуВремяИдДок(ДатаКон.ПолучитьПозицию())+глMeta1С.ЗначениеВСтрокуБД(ДатаКон.ТекущийДокумент());
           КонецЕсли;
       ИначеЕсли ТипЗначения(ДатаНач) = 3 Тогда //3 - тип данных Дата;
           МетаНомер = ""+глMeta1С.ПолучитьСтрИзДаты(ДатаКон)+"Z";
       ИначеЕсли ПустоеЗначение(Дата(ДатаНач)) = 0 Тогда
           МетаНомер = ""+глMeta1С.ПолучитьСтрИзДаты(Дата(ДатаНач))+"Z";
       КонецЕсли;
       Если ПустоеЗначение(МетаНомер) = 0 Тогда
             СкульЗапрос=СкульЗапрос+"
             |and TabJ.DATE_TIME_IDDOC<='"+МетаНомер+"'
           |";
       КонецЕсли;
   КонецЕсли;
   Если ПустоеЗначение(СокрЛП(ТипДок)) = 0 Тогда
       СтрокПоиск = СокрЛП(ТипДок);
       КолСимв       = СтрЧислоВхождений(СтрокПоиск,",");
       Если КолСимв <> 0 Тогда
           КолСимв = КолСимв + 1;
           СтрокаДляЗапроса = "";
           Пока КолСимв <> 0 Цикл
               
               Если КолСимв = 1 Тогда //Он один
                   СтрокПолуч = СокрЛП(СтрокПоиск);
               Иначе
                   НомСимв       = Найти(СтрокПоиск,",");
                   Если НомСимв = 0 Тогда
                       Сообщить("Ошибка в разборе команды: "+ТипДок);
                   КонецЕсли;
                   СтрокПолуч = СокрЛП(Сред(СтрокПоиск,1,НомСимв-1));
                   СтрокПоиск = СокрЛП(Сред(СтрокПоиск,НомСимв+1));
               КонецЕсли;
               
               Если ПустоеЗначение(СтрокПолуч) = 0 Тогда
                   ЧтоЭто = ЭтоЧисло(СтрокПолуч);
                   Если СуществуетТакойВидДок(ЧтоЭто) = 1 Тогда
                       МетаНомер = глMeta1С.ИДДокумента(ЧтоЭто);
                       СтрокаДляЗапроса = СтрокаДляЗапроса + ?(ПустоеЗначение(СтрокаДляЗапроса)=1,"",",") + "'"+МетаНомер+"'";
                   КонецЕсли;
               КонецЕсли;
               
               КолСимв = КолСимв - 1;
           КонецЦикла;
           Если ПустоеЗначение(СтрокаДляЗапроса) = 0 Тогда
               СкульЗапрос=СкульЗапрос+"
               |and TabJ.IDDOCDEF in ("+СтрокаДляЗапроса+")
               |";  // '"+глMeta1С.ИДДокумента(ТипДок)+"'
           КонецЕсли;
       Иначе
           МетаНомер  = "";
           СтрокПолуч = СокрЛП(ТипДок);
           
           Если ПустоеЗначение(СтрокПолуч) = 0 Тогда
               ЧтоЭто = ЭтоЧисло(СтрокПолуч);
               Если СуществуетТакойВидДок(ЧтоЭто) = 1 Тогда
                   МетаНомер = глMeta1С.ИДДокумента(ЧтоЭто);
                   СтрокаДляЗапроса = СтрокаДляЗапроса + ?(ПустоеЗначение(СтрокаДляЗапроса)=1,"",",") + "'"+МетаНомер+"'";
               КонецЕсли;
           КонецЕсли;
           
           Если ПустоеЗначение(МетаНомер) = 0 Тогда
               СкульЗапрос=СкульЗапрос+"
               |and TabJ.IDDOCDEF='"+МетаНомер+"'
               |";
           КонецЕсли;
       КонецЕсли;
   КонецЕсли;
   Если Проведен = 1 Тогда
       Если БезУдаленых = 1 Тогда
           СкульЗапрос=СкульЗапрос+"
           |and (((TabJ.CLOSED & 1) = 1) or (TabJ.IsMark = 0))
           |";
       ИначеЕсли БезУдаленых = 2 Тогда
           СкульЗапрос=СкульЗапрос+"
           |and (((TabJ.CLOSED & 1) = 1) or (TabJ.IsMark <> 0))
           |";
       Иначе
           СкульЗапрос=СкульЗапрос+"
           |and ((TabJ.CLOSED & 1) = 1)
           |";
       КонецЕсли;
   Иначе
       Если БезУдаленых = 1 Тогда
           СкульЗапрос=СкульЗапрос+"
           |and (TabJ.IsMark = 0)
           |";
       ИначеЕсли БезУдаленых = 2 Тогда
           СкульЗапрос=СкульЗапрос+"
           |and (TabJ.IsMark <> 0)
           |";
       КонецЕсли;
   КонецЕсли;
   СкульЗапрос=СкульЗапрос+"
   |ORDER BY
   |TabRod.CHILD_DATE_TIME_IDDOC "+?(Порядок=0,"ASC","DESC")+"
   |";
   
   Если глRecord1С.Подготовить(СкульЗапрос)=0 Тогда
       Сообщить("Запрос не прошел "+глRecord1С.ПолучитьОписаниеОшибки()+"
       |"+СкульЗапрос,"!");
       Возврат Рез;
   КонецЕсли;
   
   ТЗЗапрос = 0;
   ТЗЗапрос = СоздатьОбъект("ТаблицаЗначений");
   Попытка
       ЗначСпс = глRecord1С.ВыполнитьИнструкцию(,ТЗЗапрос,1);
   Исключение
       Сообщить("ВыполнитьИнструкцию: "+ОписаниеОшибки());
   КонецПопытки;
   
   Попытка
       глRecord1С.Закрыть();
   Исключение
       Сообщить("Закрыть SQL запрос: "+ОписаниеОшибки());
   КонецПопытки;
   
   Если ТипЗначенияСтр(ТЗЗапрос) <> "ТаблицаЗначений" Тогда
       Сообщить("Нет нужного параметра!","!");
   ИначеЕсли ТЗЗапрос.КоличествоКолонок() = 0 Тогда
       ТЗЗапрос.НоваяКолонка("Док","Документ");
       Сообщить("Запрос не выполнен:
       |"+СкульЗапрос,"!");
   Иначе
       Рез = ТЗЗапрос;
   КонецЕсли;
   
   Возврат Рез;
КонецФункции
2 monsterZE
 
26.10.12
11:51
спасибо!
3 ЧеловекДуши
 
26.10.12
11:52
(2)Если делаешь подключение к другой БД, то не помешает :)
4 ЧеловекДуши
 
26.10.12
11:54
+(2) Если понравилось, то dbo.sp_tohex(TabJ.IDDOCDEF,4)

//val - 10-ное число, len1 - количество символов
ТекстЗапроса="
|if   Object_ID('sp_tohex') is null
|Begin
|Exec('
|create FUNCTION  sp_tohex( val int, @len1 int) RETURNS varchar(9)
|AS
|begin
|declare @v int;
|declare @tval varchar(9);
|set @v = val;
|set @tval = '''';
|
|while (@v > 0)
|begin
|   set @tval = SUBSTRING(''0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'',1+@v%36,1)+@tval;
|   set @v = @v/36;
|end;
|
|if @tval='''' set @tval=''0'';
|
|while (len(@tval) < @len1)
|begin
|set @tval = '' ''+@tval;
|end;
|RETURN(@tval);
|end
|')";
5 monsterZE
 
26.10.12
11:57
(4) угу, большое спасибо =)
6 ЧеловекДуши
 
26.10.12
12:26
+(2)Вот еще немного помощи...

Функция ЭтоЧисло(СтрокПолуч)
   Перем Рез;
   
   Рез = СокрЛП(СтрокПолуч);
   
   Если Число(Рез) <> 0 Тогда
       Если СтрДлина(Строка(Число(Рез))) = СтрДлина(Рез) Тогда
           Рез = Число(Рез);
       КонецЕсли;
   КонецЕсли;
   
   Возврат Рез;
КонецФункции    // ЭтоЧисло(СтрокПолуч)

Функция СуществуетТакойВидДок(ЧтоЭто)
   Перем Рез;
   
   Рез = 0;
   
   Если Метаданные.Документ(ЧтоЭто).Выбран() = 1 Тогда
       Рез = 1;
   КонецЕсли;
   
   Возврат Рез;
КонецФункции    // СуществуетТакойВидДок(ЧтоЭто)
7 monsterZE
 
27.10.12
10:28
вечером ожидал сюрпиз из ошибок выполнения запросов к основной базе.. =) вобщем в моем случае сабж необходим. или может я просто не то закрываю?
Запрос  = СоздатьОбъект("ODBCRecordSet");
глМД    = СоздатьОбъект("MetaDataWork");
ОДБЦ_ДБ = СоздатьОбъект("ODBCDataBase");

Функция ИнитБазыСКЛ()
   
   _Сервер                = СокрЛП(Константа.СКЛ_Сервер);
   _ИмяИБ                = СокрЛП(Константа.СКЛ_ИмяИБ);
   _ИмяПользователя    = СокрЛП(Константа.СКЛ_ИмяПольз);
   _ПарольПользователя = СокрЛП(Константа.СКЛ_ПарольПольз);
   
   СтрокаСоединения = "DRIVER={SQL Server}"+
                      ";SERVER="+СокрЛП(_Сервер)+
                      ";DATABASE="+СокрЛП(_ИмяИБ)+
                      ";UID="+СокрЛП(_ИмяПользователя)+
                      ";PWD="+СокрЛП(_ПарольПользователя)+";";
                 
   ТекСКЛТаб = СокрЛП(Константа.СКЛ_Таб);
   Возврат(ОДБЦ_ДБ.Соединение(СтрокаСоединения));
   
КонецФункции

Если ИнитБазыСКЛ() = 0 Тогда
   Сообщить("Ошибка подключения к базе данных СКЛ!");
   ИнитСКЛ_ОК = -1;
   Возврат;
КонецЕсли;    
   
Запрос.УстБД(ОДБЦ_ДБ);
[..]
Результат = Запрос.ВыполнитьИнструкцию(ТекстЗапроса);
[..]
ОДБЦ_ДБ.Закрыть();
Запрос.УстБД1С(); // без этого к основной базе не возвращалось
.Закрыть() и у ODBCRecordSet и у ODBCDataBase
одно закрывает текущую выборку, второе установленное ранее соединение
Компьютеры — прекрасное средство для решения проблем, которых до их появления не было.