-- Шаблон создан мастером бланков
-- 03.11.2003 10:22:19
--
БланкСШаблоном "Библиотека SQL";

Proc ШаблонПриОткрытии(l:l);
-- Message('Библиотека SQL^MРусспромоценка 2007г');
 Message('Библиотека SQL^MТБ-БЮДЖЕТ 2009г');
 close;
end;

var БылЗаполненБлокСхемыДоступа:l;
var buf       []:s;
var crdlist   []:s;
var userlist  []:s;
var dblist    []:s;
var SQLcrdlist[]:s;
var OnlyRd[]:l;
var CanIns[]:l;
var CanUpd[]:l;
var CanDel[]:l;
var CanVis[]:l;

var CanCMF[]:l; --ClosedModFob
var KalkCMF[]:l; --проверка на разрешение снятия ClosedModFob
var ServFilter[]:s; --Постоянный фильтр на сервере на данную картотеку
var SetRightUser[]:l; --есть изменения стандартных прав пользователя
var OnlyRdUser[]:l;
var CanInsUser[]:l;
var CanUpdUser[]:l;
var CanDelUser[]:l;
var CanCMFUser[]:l; --ClosedModFob
var FilterUser[]:s; --Постоянный фильтр на данную картотеку
var CardDBType[]:s; --

--func  Get_SQL_rezS(crd_tbb:s;lst:ls;show_msg:l)
-- var rez:s;
-- var waSQL:i;
-- var lst:S;
-- var ll:L;
--  ^rez;
--end;

func  Get_SQL_SERVERPROPERTY(crd_tbb:s;param:s;show_msg:l):s; -- param=MachineName,ProductVersion,ResourceVersion,ServerName,Edition,ComputerNamePhysicalNetBIOS
 var rez:s;
 var waSQL:i;
 var lst:S;
 var ll:L;
 lst="SELECT cast(SERVERPROPERTY('"+param+"') as varchar) REZ";
  if show_msg:ОкноВыполненияПоказать(2, "Запрос к базе данных...");fi;
  try
  waSQL=ОткрытьРабочуюОбластьSQL('',lst,crd_tbb);
   ll=true;
   if show_msg:ОкноВыполненияЗакрыть;fi;
  except
   ll=false;
   if show_msg:ОкноВыполненияЗакрыть;fi;
   Raise;
  end;
  if ll:
     if records(waSQL)>0:rez=getfields(waSQL,1,'REZ');fi;
     CloseWorkArea(waSQL);
  fi;
  ^rez;
end;

func  Get_SQL_SERVERPROPERTY_VERSION(crd_tbb:s;show_msg:l):s; --
 var rez:s;
 var waSQL:i;
 var lst:S;
 var ll:L;
 lst='SELECT @@VERSION REZ' ;
-- lst="SELECT cast(SERVERPROPERTY('"+param+"') as varchar) REZ";
  if show_msg:ОкноВыполненияПоказать(2, "Запрос к базе данных...");fi;
  try
  waSQL=ОткрытьРабочуюОбластьSQL('',lst,crd_tbb);
   ll=true;
   if show_msg:ОкноВыполненияЗакрыть;fi;
  except
   ll=false;
   if show_msg:ОкноВыполненияЗакрыть;fi;
   Raise;
  end;
  if ll:
     if records(waSQL)>0:rez=getfields(waSQL,1,'REZ');fi;
     CloseWorkArea(waSQL);
  fi;
  ^rez;
end;

func  Get_SQL_SERVERPROPERTY_Platform(crd_tbb:s;show_msg:l):s; --Intel X86
 var rez,p:s;
  rez = Get_SQL_SERVERPROPERTY_VERSION(crd_tbb,show_msg);
  rez = substr(rez,1,pos(')',rez)-1);
  rez = substr(rez,pos('(',rez)+1,256);
  ^rez;
end;

func  Get_SQL_SERVERPROPERTY_all(crd_tbb:s;show_msg:l):ls;
var p,all:s;
var msgformat:ls;
var wc,j:i;
 all='MachineName,ComputerNamePhysicalNetBIOS,ServerName,Edition,ProductVersion,ResourceVersion,EngineEdition,InstanceName,ProductLevel,ProcessID,Platform';
 wc=WordsCount(all,',');
 for j=1..wc do
  p=ExtractWord(j,all,',');
  msgformat= msgformat+ p + '='+Get_SQL_SERVERPROPERTY(crd_tbb,p,show_msg);
  if j<wc:msgformat=msgformat+'^M';fi;
 od;
 ^msgformat;
end;

func  Get_SQL_VERSION(crd_tbb:s;show_msg:l):s; -- Express Edition
 ^Get_SQL_SERVERPROPERTY(crd_tbb,'ProductVersion',show_msg);
end;

func  Get_SQL_VERSION_FULL(crd_tbb:s;show_msg:l):s; -- Express Edition 2005 SP4 (9.00.5000.00-Intel X86)
 var val,yyyy,x64:s;
 val=Get_SQL_VERSION(crd_tbb,show_msg);
 if match(val,'7.*') :yyyy='7';
  | match(val,'8.*') :yyyy='2000';
  | match(val,'9.*') :yyyy='2005';
  | match(val,'10.00.*'):yyyy='2008';
  | match(val,'10.50.*'):yyyy='2008R2';
  | match(val,'11.*'):yyyy='2012';
  | match(val,'12.*'):yyyy='2014';
  | true:yyyy='0000';
 fi;
 x64=Get_SQL_SERVERPROPERTY_Platform(crd_tbb,show_msg);
 val=Get_SQL_SERVERPROPERTY(crd_tbb,'Edition',show_msg)+' '+yyyy+' '+Get_SQL_SERVERPROPERTY(crd_tbb,'ProductLevel',show_msg)+' ('+val+'-'+x64+')';
 ^val;
end;

func ExistsServFilter(ИМЯКРТ:s):l;
var res:l;
var wa:i;
  if ExistsCardFile(ИМЯКРТ):
    try
     wa=OpenWorkArea(ИМЯКРТ,'','1=0) and (1=0');  --  в случае наличия доп фильтра на сервере получаем:  (1=0) and (1=0) and (фильтрсервера)
     CloseWorkArea(wa);
      res=true;
    except
      res=false;  -- нет доп фильтра, получаем неправльный фильрт: 1=0) and (1=0
    end;
  fi;
  ^res;
end;

func GetServFilter(ИМЯКРТ:s):s;
var res:s;
var wa:i;
  if ExistsCardFile(ИМЯКРТ):
    try
     wa=OpenWorkArea(ИМЯКРТ,'','1=0) and ({1}={ukey}');  --  в случае наличия доп фильтра на сервере получаем:  (1=0) and (1=0) and (фильтрсервера)
--     wa=OpenWorkArea(ИМЯКРТ,'','(1=0) and (1=0');  --  в случае наличия доп фильтра на сервере получаем:  (1=0) and (1=0) and (фильтрсервера)
     CloseWorkArea(wa);
      res=' ';
    except
    Message(Format('Сообщение: %s^MКод: %d', ErrorMessage, ErrorCode), mtError);
      res='';  -- нет доп фильтра, получаем неправльный фильрт: 1=0) and (1=0
--      Raise;
    end;
  fi;
  ^res;
end;


func GetNomCRD(ИМЯКРТ:s):i;
 var ii,j:i;
 if не БылЗаполненБлокСхемыДоступа:--инициализация при первом обращении в данной сессии
-- if 1=1:--инициализация при первом обращении в данной сессии
  БылЗаполненБлокСхемыДоступа=true;
  ClearVariable(Раб.SQL.crdlist   );
  ClearVariable(Раб.SQL.userlist  );
  ClearVariable(Раб.SQL.dblist    );
  ClearVariable(Раб.SQL.SQLcrdlist);
  ClearVariable(Раб.SQL.OnlyRd);
  ClearVariable(Раб.SQL.CanIns);
  ClearVariable(Раб.SQL.CanIns);
  ClearVariable(Раб.SQL.CanUpd);
  ClearVariable(Раб.SQL.CanDel);
  ClearVariable(Раб.SQL.CanVis);
  ClearVariable(Раб.SQL.CanCMF);
  ClearVariable(Раб.SQL.KalkCMF);
  ClearVariable(Раб.SQL.ServFilter);
  ClearVariable(Раб.SQL.SetRightUser);
  ClearVariable(Раб.SQL.CanInsUser);
  ClearVariable(Раб.SQL.CanUpdUser);
  ClearVariable(Раб.SQL.CanDelUser);
  ClearVariable(Раб.SQL.CanCMFUser);
  ClearVariable(Раб.SQL.FilterUser);
  ClearVariable(Раб.SQL.CardDBType);

  ii=GetCardFileNames('',Раб.SQL.crdlist,false,false,'');
  SortArray(Раб.SQL.crdlist);
  for j=1..ii do
   dblist      [j]=AliasName  (crdlist[j]);
   userlist    [j]=up(UserName(dblist[j]));
   SQLcrdlist  [j]=GetRealCardfileName(crdlist[j]);
   OnlyRd      [j]=IsReadOnly (crdlist[j]);
   CanIns      [j]=CanInsert  (crdlist[j]);
   CanUpd      [j]=CanUpdate  (crdlist[j]);
   CanDel      [j]=CanDelete  (crdlist[j]);
   CanVis      [j]=IsVisible  (crdlist[j]);
   CanCMF      [j]=false;
   KalkCMF     [j]=false;
   ServFilter  [j]=if(ExistsServFilter(crdlist[j]),' ','');
   CardDBType  [j]=GetCardDBType(crdlist[j]);
   SetRightUser[j]=trim(userlist[j])<>'';
   CanCMFUser  [j]=true;
--   CanCMFUser  [j]=pos('|'+userlist[j]+'|','|ГНАТЕНКО_ВЗ|')<1;
--   CanCMFUser  [j]=pos('|'+userlist[j]+'|','|АЛДОШИНА_ИА|МАНУШКИНА_ТБ|ПИГАРОВА_ИВ|УШАКОВА_ЮВ|ЕРОХИНА_МН|СЕРВЕР|')>0;

  od;
 fi;
 ii=поискВмассиве(crdlist,ИМЯКРТ,True);
 if ii>0:^ii;
  | true:^0;
 fi;
end;
Proc RefreshCardSQLverOnBlankEditor(ИМЯКРТ:s;delay:i;OldUpdateTime:i);
 var ii,j:i;
   ОбновитьКартотеку(ИМЯКРТ,сегодня);
   ShowProgress(delay,'Обновление данных...');                                                                 --   for j=1..45000 do od;
     ii=time;
     while ExecuteFuncI('UpdateTimeSecCurrent')=OldUpdateTime do j=time;ProgressPos(time-ii); while j=time do od;  od;
   CloseProgress;--прорисовываем бланк (обновляем внешний вид)
end;

Proc SetClosedModFobSQL(db:s;crd:s;ukey:record;User:s;Value:l);
  var SQLquery:s;
    if User<>'':User=", [MODIFIEDUSER] = '"+User+"'";fi;
--    SQLquery="UPDATE "+crd+"SET [CLOSEDMODFOB] ="+if(Value,"1","0")+", [UpdateTime] = getdate() "+User+" WHERE [UKEY] = "+str(RecordToInteger(ukey));
    SQLquery="UPDATE "+crd+"SET [CLOSEDMODFOB] ="+if(Value,"1","0")+", [UpdateTime] = DATEADD(second, 1, getdate()) "+User+" WHERE [UKEY] = "+str(RecordToInteger(ukey));
    ExecuteSQL(db,SQLquery);

end;
proc SetClosedModFob(ИМЯКРТ:s;rec:record;Value:l);
  var NomCRD:i;
    NomCRD=GetNomCRD(ИМЯКРТ);
    if NomCRD<1:exit;fi;
    SetClosedModFobSQL(dblist[NomCRD],SQLcrdlist[NomCRD],rec,userlist[NomCRD],Value);
end;
proc SetClosedModFobUpdateOnBlankEditor(ИМЯКРТ:s;rec:record;Value:l;delay:i);
  var NomCRD,OldUpdateTime:i;
    NomCRD=GetNomCRD(ИМЯКРТ);
    if NomCRD<1:exit;fi;
    OldUpdateTime=ExecuteFuncI('UpdateTimeSecCurrent');

    SetClosedModFobSQL(dblist[NomCRD],SQLcrdlist[NomCRD],rec,userlist[NomCRD],Value);
    RefreshCardSQLverOnBlankEditor(ИМЯКРТ,delay,OldUpdateTime);
end;

proc SetClosedModFobUpdateOnBlankEditor_false(ИМЯКРТ:s;rec:record;delay:i;SQLver:l;CurrentRecord:l);
var l,CMF:l;
var NomCRDsql:i;
    NomCRDsql=GetNomCRD(ИМЯКРТ);
    if KalkCMF[NomCRDsql]:-- если была проверка на разрешение снятия ClosedModFob
       if CanCMF[NomCRDsql]:PutVariableL('ClosedModFob',false);if CurrentRecord:PutVariableR('CurrentRecord',nil);fi;
        | true:
          if SQLver и CanUpd[NomCRDsql] и ((CanCMFUser[NomCRDsql] и SetRightUser[NomCRDsql]) или не SetRightUser[NomCRDsql]):--попытка снять через sql
             SetClosedModFobUpdateOnBlankEditor(ИМЯКРТ,rec,false,delay);
             if CurrentRecord:PutVariableR('CurrentRecord',nil);fi;
           | true:Message('Невозможно снять блокировку!^MОбратитесь к системному администратору!');
          fi;
       fi;
     | true: -- проверки не было, пробуем снять напрямую!
       KalkCMF[NomCRDsql]=true;
       try -- попытка снять напрямую
         PutVariableL('ClosedModFob',false);if CurrentRecord:PutVariableR('CurrentRecord',nil);fi;
--         ClosedModFob=false;CurrentRecord=nil;
         CanCMF[NomCRDsql]=true;
       except -- попытка снять через sql
         CanCMF[NomCRDsql]=false;
       end;
       if not CanCMF[NomCRDsql]:
          if SQLver и CanUpd[NomCRDsql] и ((CanCMFUser[NomCRDsql] и SetRightUser[NomCRDsql]) или не SetRightUser[NomCRDsql]):--попытка снять через sql
             SetClosedModFobUpdateOnBlankEditor(ИМЯКРТ,rec,false,delay);
             if CurrentRecord:PutVariableR('CurrentRecord',nil);fi;
           | true:Message('Невозможно снять блокировку!^MОбратитесь к системногу администратору!');
          fi;
       fi;
    fi;
end;
proc SetClosedModFobUpdateOnBlankEditor_false_all(ИМЯКРТ:s;rec:record;delay:i;SQLver:l;CurrentRecord:l);
var l,CMF:l;
var NomCRDsql:i;
    NomCRDsql=GetNomCRD(ИМЯКРТ);
    if KalkCMF[NomCRDsql]:-- если была проверка на разрешение снятия ClosedModFob
       if CanCMF[NomCRDsql]:PutVariableL('ClosedModFob',false);if CurrentRecord:PutVariableR('CurrentRecord',nil);fi;
        | true:
          if SQLver и CanUpd[NomCRDsql] и ((SetRightUser[NomCRDsql]) или не SetRightUser[NomCRDsql]):--попытка снять через sql
             SetClosedModFobUpdateOnBlankEditor(ИМЯКРТ,rec,false,delay);
             if CurrentRecord:PutVariableR('CurrentRecord',nil);fi;
           | true:Message('Невозможно снять блокировку!^MОбратитесь к системногу администратору!');
          fi;
       fi;
     | true: -- проверки не было, пробуем снять напрямую!
       KalkCMF[NomCRDsql]=true;
       try -- попытка снять напрямую
         PutVariableL('ClosedModFob',false);if CurrentRecord:PutVariableR('CurrentRecord',nil);fi;
--         ClosedModFob=false;CurrentRecord=nil;
         CanCMF[NomCRDsql]=true;
       except -- попытка снять через sql
         CanCMF[NomCRDsql]=false;
       end;
       if not CanCMF[NomCRDsql]:
          if SQLver и CanUpd[NomCRDsql] и ((SetRightUser[NomCRDsql]) или не SetRightUser[NomCRDsql]):--попытка снять через sql
             SetClosedModFobUpdateOnBlankEditor(ИМЯКРТ,rec,false,delay);
             if CurrentRecord:PutVariableR('CurrentRecord',nil);fi;
           | true:Message('Невозможно снять блокировку!^MОбратитесь к системногу администратору!');
          fi;
       fi;
    fi;
end;



3_-- имена картотек в базе данных

3_--SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH
3_--db_2011.INFORMATION_SCHEMA.COLUMNS

func СловоВTBB_filter(st:s;Fields:s):s;-- работает как MATCH(Fields,"*"+st+"*")';
^Fields+" LIKE '%"+st+"%'";
end;
func СтрокуВSql_filter_crd_or_match(st:s;razd:s;crd:s;Fields:s):s; -- для каждого поля из Fields(перечислены через запятую) применяет все варианты LIKE через "or". вариантами являются каждое из слов в st - MATCH(Fields,"*"+st+"*")';
var s1,ss:s;
var lns:s;
var k,z:i;
var z1,k1:i;
 if st='':^st;fi;
 z=Количествослов(st,razd);
 z1=количествослов(Fields,',');
 lns='';
 for k=1..z do
  s1=ВыделитьСлово(k,st,razd);
  for k1=1..z1 do
    ss=СловоВTBB_filter(s1,ВыделитьСлово(k1,Fields,','));
    if lns<>'':
       lns=lns+' or ';
    fi;
    lns=lns+ss;
  od;
 od;
   ^lns;
end;

func WordsAsLike(Words:s;Field:s;word_sep:s;like_sep:s):ls;
var z,j:i;
var rez:ls;
var ss:s;
 z=WordsCount(Words,word_sep);
 if like_sep='':like_sep='or';
  | true:
    like_sep=trim(like_sep);
 fi;
 for j=1..min(1,z) do
    ss=ExtractWord(j,Words,word_sep);
    rez=Field+" LIKE '"+ss+"'";
 od;
 for j=2..z do
    ss=ExtractWord(j,Words,word_sep);
    rez=rez+" "+like_sep+" "+Field+" LIKE '"+ss+"'";
 od;
 ^"("+rez+")";
end;

Func OpenCardDistinct(ИМЯКРТ:s;filter:s;FieldList:s):i; 
-- открывает рабочую область sql на картотеку ИМЯКРТ с фильтром filter 
-- с уникальными значениями полей картполе1,картполе2,картполе1... из FieldList
-- FieldList="картполе1=полерезульт1|картполе2=полерезульт2|картполе3=полерезульт3"


^0;
end;

func datetostring_sql(dd:d):s;
 var ss:s;
 if dd=1.1.100:^'1900-01-01';fi;
 ss=датувстроку(dd);
 --ss=ВыделитьСлово(3,ss,'.')+'-'+ВыделитьСлово(2,ss,'.')+'-'+ВыделитьСлово(1,ss,'.');
 ss=ВыделитьСлово(3,ss,'.')+ВыделитьСлово(2,ss,'.')+ВыделитьСлово(1,ss,'.')+' 00:00:00.0';
 ^ss;
end;

Func field_as_datetime(field:s):s;-- обертка преобразования поля field datetime в строку формата yyyymmdd hh:mm:ss:mmm
  field="replace(convert(varchar,"+field+",121),'-','') "+field;
  ^field;
end;

Func field_as_dateTB(field:s):s;-- обертка преобразования поля field datetime в строку формата dd.mm.yyyy
  field="convert(varchar,"+field+",104) "+field;
  ^field;
end;

Func field_as_datetimeTB(field:s):s;-- обертка преобразования поля field datetime в строку формата dd.mm.yyyy hh:mm:ss
  field="convert(varchar,"+field+",104)+' '+convert(varchar,"+field+",108) "+field;
  ^field;
end;

Func GetWorkAreaSQL(SelectSql:ls;crd_tbb:s;show_msg:l):i;
 var waSQL:i;
 var ll:L;
  if show_msg:ОкноВыполненияПоказать(2, "Запрос к базе данных...");fi;
  try
  waSQL=ОткрытьРабочуюОбластьSQL('',SelectSql,crd_tbb);
   ll=true;
   if show_msg:ОкноВыполненияЗакрыть;fi;
  except
   ll=false;
   if show_msg:ОкноВыполненияЗакрыть;fi;
   Raise;
  end;
  if ll:^waSQL;
   | true:^0;
  fi;
end;

func  LoadRowsSelect(crd_tbb:s;select_sql:ls;show_msg:l;field_to_field:ls;bln_name:s):i; -- загружает данные запроса в массивы бланка, возвращает кол загруженных строк
-- crd_tbb        -- имя картотеки ТБ для коннекта с sql
-- select_sql     -- sql запрос возвращающий поля состыкованные в field_to_field
-- show_msg       -- флаг показывать градусник отработки запроса (удобно при длительном исполнении)
-- field_to_field -- строка вида массив_бланка1=ИмяСтолбцаТаблицы1|массив_бланка2=ИмяСтолбцаТаблицы2|массив_бланка3=ИмяСтолбцаТаблицы3
-- bln_name       -- имя бланка в который будут грузится данные(пустая строка - грузим в текущий бланк)
 var rez:i;
 var waSQL:i;
 var ll:L;
 var lnlst:i;
 rez=-1;
  if show_msg:ОкноВыполненияПоказать(2, "Запрос к базе данных...");fi;
  try
  waSQL=ОткрытьРабочуюОбластьSQL('',select_sql,crd_tbb);
  rez=ВзятьКакМассивSQL(waSQL, bln_name, field_to_field );
   ll=true;
   if show_msg:ОкноВыполненияЗакрыть;fi;
  except
   ll=false;
   if show_msg:ОкноВыполненияЗакрыть;fi;
   CloseWorkArea(waSQL);
   Raise;
  end;
  if ll:
     CloseWorkArea(waSQL);
  fi;
  ^rez;
end;


Func GetFieldSQL_s(waSQL:i;field:s;iter:i):s; -- взять значение поля String из рабочей области SQL
-- особенность! имя поля field может быть просто именем поля, а может быть составным или функцией, 
-- в этом случае берется обязательный алиас=последнему слову в field через пробел
--field="cast(ukey as varchar)+' '+cast(updatetime as varchar) ukey_updatetime" - алиас=ukey_updatetime
 var z:i;
 var rez:s;
  if waSQL<1:^rez;fi;
  z=количествослов(field,' ');
  if z>0:
     field=ВыделитьСлово(z,field,' ');
  fi;
  rez=getfields(waSQL,iter,field);
  ^rez;
end;

Func GetFieldSQL_i(waSQL:i;field:s;iter:i):i; -- взять значение поля Integer из рабочей области SQL
-- особенность! имя поля field может быть просто именем поля, а может быть составным или функцией, 
-- в этом случае берется обязательный алиас=последнему слову в field через пробел
--field="ukey+cast(updatetime as int) ukey_updatetime" - алиас=ukey_updatetime
 var z:i;
 var rez:i;
  if waSQL<1:^rez;fi;
  z=количествослов(field,' ');
  if z>0:
     field=ВыделитьСлово(z,field,' ');
  fi;
  rez=getfieldi(waSQL,iter,field);
  ^rez;
end;

Func GetFieldSQL_l(waSQL:i;field:s;iter:i):l; -- взять значение поля Integer из рабочей области SQL, результат берется как Logical
-- особенность! имя поля field может быть просто именем поля, а может быть составным или функцией, 
-- в этом случае берется обязательный алиас=последнему слову в field через пробел
  ^getfieldi(waSQL,iter,field)<>0;
end;

Func GetFieldSQL_d(waSQL:i;field:s;iter:i):d; -- взять значение поля Date из рабочей области SQL
-- особенность! имя поля field может быть просто именем поля, а может быть составным или функцией, 
-- в этом случае берется обязательный алиас=последнему слову в field через пробел
 var z:i;
 var rez:d;
  if waSQL<1:^rez;fi;
  z=количествослов(field,' ');
  if z>0:
     field=ВыделитьСлово(z,field,' ');
  fi;
  rez=getfieldd(waSQL,iter,field);
  ^rez;
end;

Func GetFieldSQL_n(waSQL:i;field:s;iter:i):n; -- взять значение поля Numeric из рабочей области SQL
-- особенность! имя поля field может быть просто именем поля, а может быть составным или функцией, 
-- в этом случае берется обязательный алиас=последнему слову в field через пробел
 var z:i;
 var rez:n;
  if waSQL<1:^rez;fi;
  z=количествослов(field,' ');
  if z>0:
     field=ВыделитьСлово(z,field,' ');
  fi;
  rez=getfieldn(waSQL,iter,field);
  ^rez;
end;


Func GetSelectFieldl(lst:ls;crd_tbb:s;field:s;iter:i;show_msg:l):l; -- взять значение поля Integer из Select SQL, результат берется как Logical
 var rez:l;
 var waSQL,z:i;
 var ll:L;
  waSQL=GetWorkAreaSQL(lst,crd_tbb,show_msg);
  if waSQL<1:^rez;fi;
  if records(waSQL)<iter:
     CloseWorkArea(waSQL);
   ^rez;
  fi;
  try
    rez=GetFieldSQL_l(waSQL,field,iter);
    CloseWorkArea(waSQL);
  except
    CloseWorkArea(waSQL);
    if show_msg:ОкноВыполненияЗакрыть;fi;
    Raise;
  end;
  ^rez;
end;

Func GetSelectFieldS(lst:ls;crd_tbb:s;field:s;iter:i;show_msg:l):s;-- взять значение поля String из Select SQL
 var rez:s;
 var waSQL,z:i;
 var ll:L;
  waSQL=GetWorkAreaSQL(lst,crd_tbb,show_msg);
  if waSQL<1:^rez;fi;
  if records(waSQL)<iter:
     CloseWorkArea(waSQL);
   ^rez;
  fi;
  try
    rez=GetFieldSQL_s(waSQL,field,iter);
    CloseWorkArea(waSQL);
  except
    CloseWorkArea(waSQL);
    if show_msg:ОкноВыполненияЗакрыть;fi;
    Raise;
  end;
  ^rez;
end;

Func GetSelectFieldI(lst:ls;crd_tbb:s;field:s;iter:i;show_msg:l):i;--взять значение поля Integer из Select SQL
 var rez:i;
 var waSQL,z:i;
 var ll:L;
  waSQL=GetWorkAreaSQL(lst,crd_tbb,show_msg);
  if waSQL<1:^rez;fi;
  if records(waSQL)<iter:
     CloseWorkArea(waSQL);
   ^rez;
  fi;
  try
    rez=GetFieldSQL_i(waSQL,field,iter);
    CloseWorkArea(waSQL);
  except
    CloseWorkArea(waSQL);
    if show_msg:ОкноВыполненияЗакрыть;fi;
    Raise;
  end;
  ^rez;
end;

Func GetSelectFieldN(lst:ls;crd_tbb:s;field:s;iter:i;show_msg:l):N; --взять значение поля Numeric из Select SQL
 var rez:N;
 var waSQL,z:i;
 var ll:L;
  waSQL=GetWorkAreaSQL(lst,crd_tbb,show_msg);
  if waSQL<1:^rez;fi;
  if records(waSQL)<iter:
     CloseWorkArea(waSQL);
   ^rez;
  fi;
  try
    rez=GetFieldSQL_N(waSQL,field,iter);
    CloseWorkArea(waSQL);
  except
    CloseWorkArea(waSQL);
    if show_msg:ОкноВыполненияЗакрыть;fi;
    Raise;
  end;
  ^rez;
end;

Func GetSelectFieldD(lst:ls;crd_tbb:s;field:s;iter:i;show_msg:l):D;--взять значение поля Date из Select SQL
 var rez:D;
 var waSQL,z:i;
 var ll:L;
  waSQL=GetWorkAreaSQL(lst,crd_tbb,show_msg);
  if waSQL<1:^rez;fi;
  if records(waSQL)<iter:
     CloseWorkArea(waSQL);
   ^rez;
  fi;
  try
    rez=GetFieldSQL_D(waSQL,field,iter);
    CloseWorkArea(waSQL);
  except
    CloseWorkArea(waSQL);
    if show_msg:ОкноВыполненияЗакрыть;fi;
    Raise;
  end;
  ^rez;
end;

Func SelectGetAgr(crd_sql:s;field:s;crd_sql_filter:ls;AVG:s):ls; -- Получаем готовый запрос SQL на поле таблицы field с использованием агрегатной функции по этому полю
-- где AVG - одно из значений=min,max,count,avg,sum
 if crd_sql_filter<>'':crd_sql_filter=' where '+crd_sql_filter;fi;
 ^'SELECT '+AVG+'('+field+') as rezmaxfield from '+crd_sql+' WITH (NOLOCK)'+crd_sql_filter;
end;

Func SelectGetByAgr(crd_sql:s;field:s;fieldAgr:s;crd_sql_filter:ls;AVG:s):ls; -- Получаем готовый запрос SQL на любое поле таблицы field с использованием агрегатной функции по полю fieldAgr 
-- где AVG - одно из значений=min,max,count,avg,sum
var Select:ls;
 Select='SELECT * from '+crd_sql+' WITH (NOLOCK)';
 if crd_sql_filter<>'':Select=Select+' where '+crd_sql_filter;fi;
 Select='('+Select+') s1,'+'('+SelectGetAgr(crd_sql,fieldAgr,crd_sql_filter,AVG)+') s0';
 Select='SELECT '+field+' from '+Select+' where s1.'+fieldAgr+'=s0.rezmaxfield';
 ^Select;
end;

Func GetAgrFieldI(crd_tbb:s;crd_sql:s;field:s;crd_sql_filter:ls;AVG:s;show_msg:l):i;--значение поля таблицы crd_sql с использованием агрегатной функции по этому полю
--AVG=max min count avg sum
--Раб.sql.GetAgrFieldI(crd,crdsql,'ПРИЗНАК','','max',false)=максимальное значение поля ПРИЗНАК
 ^GetSelectFieldI(SelectGetAgr(crd_sql,field,crd_sql_filter,AVG),crd_tbb,'rezmaxfield',1,show_msg);
end;

Func GetAgrFieldN(crd_tbb:s;crd_sql:s;field:s;crd_sql_filter:ls;AVG:s;show_msg:l):n;--значение поля таблицы crd_sql с использованием агрегатной функции по этому полю
--AVG=max min count avg sum
 ^GetSelectFieldN(SelectGetAgr(crd_sql,field,crd_sql_filter,AVG),crd_tbb,'rezmaxfield',1,show_msg);
end;

Func GetAgrFieldD(crd_tbb:s;crd_sql:s;field:s;crd_sql_filter:ls;AVG:s;show_msg:l):d;--значение поля таблицы crd_sql с использованием агрегатной функции по этому полю
--AVG=max min
 ^GetSelectFieldD(SelectGetAgr(crd_sql,field,crd_sql_filter,AVG),crd_tbb,'rezmaxfield',1,show_msg);
end;

Func GetAgrFieldS(crd_tbb:s;crd_sql:s;field:s;crd_sql_filter:ls;AVG:s;show_msg:l):S;--значение поля таблицы crd_sql с использованием агрегатной функции по этому полю
--AVG=max min
 ^GetSelectFieldS(SelectGetAgr(crd_sql,field,crd_sql_filter,AVG),crd_tbb,'rezmaxfield',1,show_msg);
end;

Func GetFieldSByAgrField(crd_tbb:s;crd_sql:s;field:s;fieldAgr:s;crd_sql_filter:ls;AVG:s;show_msg:l):S;--значение поля=field таблицы crd_sql с использованием агрегатной функции по полю fieldAgr
--AVG=max min
--Раб.sql.GetFieldSByAgrField(crd,crdsql,'ПРИЗНАК','UPDATETIME','','max',false)=Значение поля ПРИЗНАК с максимальным значением поля UPDATETIME
 ^GetSelectFieldS(SelectGetByAgr(crd_sql,field,fieldAgr,crd_sql_filter,AVG),crd_tbb,field,1,show_msg);
end;

Func GetFieldIByAgrField(crd_tbb:s;crd_sql:s;field:s;fieldAgr:s;crd_sql_filter:ls;AVG:s;show_msg:l):I;--значение поля=field таблицы crd_sql с использованием агрегатной функции по полю fieldAgr
--AVG=max min
 ^GetSelectFieldI(SelectGetByAgr(crd_sql,field,fieldAgr,crd_sql_filter,AVG),crd_tbb,field,1,show_msg);
end;


Func GetAgrFieldL(crd_tbb:s;crd_sql:s;field:s;crd_sql_filter:ls;AVG:s;show_msg:l):l;--значение поля=field таблицы crd_sql с использованием агрегатной функции по полю fieldAgr
--AVG=max min
 var where:s;
 where=' where ('+field+')<>0';
 if crd_sql_filter<>'':crd_sql_filter=where+' and ('+crd_sql_filter+')';
  | true:crd_sql_filter=where;
 fi;
 ^GetSelectFieldL('SELECT '+AVG+'('+field+') as rezmaxfield from '+crd_sql+' WITH (NOLOCK)'+crd_sql_filter,crd_tbb,'rezmaxfield',1,show_msg);
end;

func  COUNTinCRD(crd_tbb:s;crd_sql:s;filter:s;show_msg:l):i; -- количество строк в картотеке SQL (не учитывается фильтр наложенный в схеме доступа на сервере ТБ)
-- crd_tbb        -- имя картотеки ТБ для коннекта с sql
-- crd_sql        -- реальное имя картотеки в базе данных
-- filter         -- sql фильтр на картотеку crd_sql
-- show_msg       -- флаг показывать градусник отработки запроса (удобно при длительном исполнении)

 ^GetAgrFieldI(crd_tbb,crd_sql,'*',filter,'count',show_msg);
end;



func  LoadRowsSelectByAgrField(crd_tbb:s;crd_sql:s;fields:s;fieldAgr:s;crd_sql_filter:ls;AVG:s;show_msg:l;field_to_field:ls;bln_name:s):i; -- загружает данные запроса в массивы бланка, возвращает кол загруженных строк
      ^LoadRowsSelect(crd_tbb,SelectGetAgr(crd_sql,fields,crd_sql_filter,AVG),show_msg,field_to_field,bln_name);                           -- fields=список полей, строки у которых fieldAgr имеет макисальное(минимальное) значеник
end;

var tablist   []:s;



func Выбор_db_sql(crd:s;filter:s;db_list_not_in:s;alternate_cmnt:s):s;-- имя выбранной базы данных
-- crd = любая картотека доступная текущему пользователю для коннекта к серверу sql
-- filter=дополнительный пользовательский фильтр пример "name like '%14%'" - все базы данных содержащие в наименовании 14
-- db_list_not_in= список баз данных через запятую исключенных из выбора (по умолчанию в него входят служебные базы master,tempdb,model,msdb)
-- alternate_cmnt=описание(заголовок) окна выбора базы данных
var SQLquery:ls;
var ss:s;
var wasql,j,z,rs:i;
 db_list_not_in="master,tempdb,model,msdb,"+trim(db_list_not_in);
 z=КоличествоСлов(db_list_not_in,',');
 for j=1..z do
   ss=trim(ВыделитьСлово(j,db_list_not_in,','));
   if ss<>'':
      rs=rs+1;
      ss="'"+ss+"'";
      SQLquery=SQLquery+if(rs=1,"",",")+ss;
   fi;
 od;
 SQLquery="SELECT name FROM sys.databases where (name not in("+SQLquery+"))";
 if filter<>'':SQLquery=SQLquery+" and ("+filter+")";fi;
 wasql=OpenWorkAreaSQL('',SQLquery,crd);
 ClearVariable(Раб.SQL.buf);
 rs=GetAsArraySQL(wasql,'Раб.SQL','buf=name');
 CloseWorkArea(wasql);
 if lengthofarray(Раб.SQL.buf)<1:^'';fi;
 j=alternate(alternate_cmnt,Раб.SQL.buf);
 if j>0:^buf[j];fi;
 ^'';
end;

func existcrd_sql(db_from:s;crd:s;small_crdsql:s):l; -- проверяет наличие картотеки small_crdsql в любой базе данных db_from, small_crdsql=короткое имя картотеки
-- crd         = любая картотека доступная текущему пользователю для коннекта к серверу sql
-- db_from     = база данных
-- small_crdsql=короткое имя картотеки
var SQLquery:ls;
var wasql,j,z,rs:i;
 SQLquery="SELECT name FROM "+db_from+"..sysobjects WHERE type='U' and name='"+small_crdsql+"'";
 wasql=OpenWorkAreaSQL('',SQLquery,crd);
 rs=records(wasql);
 CloseWorkArea(wasql);
 ^rs>0;
end;

func find_table_sql(crd:s;db_to_list:s):s;-- возвращает полное имя картотеки найденой в списке баз данных через запятую
-- crd         = имя картотеки для поиска в списке баз данных db_to_list, она же - любая картотека доступная текущему пользователю для коннекта к серверу sql,
-- db_to_list  = список имен баз данных через запятую
var z,j:i;
var db_to:s;
 z=количествослов(db_to_list,',');
 db_to='';
 for j=1..z do
  db_to=ВыделитьСлово(j,db_to_list,',');
  if existcrd_sql(db_to,crd,crd):
     ^db_to+".dbo."+crd;
  fi;
 od;
 ^'';
end;

proc copy_table_sql(crd:s;db_to_list:s;crdfilter:s;ClearCrd_to:l);
-- переносит данные из картотеки crd, включая ее подтаблицы, подключенной в текущем плане бухгалтерии с учетом фильтра ТБ=crdfilter на картотеку crd
-- перенос происходит в одну из баз данных перечисленных в db_to_list через запятую, в первую найденую картотеку с таким же именем.
-- обязательное условие - структура картотек "откуда" должна быть идентична структуре картотек "куда"
-- ClearCrd_to=удалить данные в получателе перед загрузкой
-- Вся выгрузка происходит без учета фильтра наложенного на картотеку на сервере ТБ. Учитывается только не sql, а обычный фильтр ТБ=crdfilter наложенный на выгружаемую картотеку
var realcrd,db_from,SQLfilter,db_to:s;
var SQLquery:ls;
var wasql,j,z,rs:i;
 realcrd=GetRealCardfileName(crd);
 db_from=ВыделитьСлово(1,realcrd,'.');
 z=количествослов(db_to_list,',');
 db_to=find_table_sql(crd,db_to_list);
 if db_to<>'':db_to=ВыделитьСлово(1,db_to,'.');
  | true:exit;
 fi;
 if CardFilterToSQL(crd,'t0.',crdfilter,SQLfilter):
    SQLfilter=trim(SQLfilter);
 fi;
    SQLfilter=trim(SQLfilter);

 SQLquery="SELECT name FROM "+db_from+"..sysobjects WHERE type='U' and (name like '"+crd+"@%' or name='"+crd+"') order by name";
 wasql=OpenWorkAreaSQL('',SQLquery,crd);
 try
  rs=ВзятьКакМассивSQL(wasql,'Раб.SQL','tablist=name');
 Finally
  CloseWorkArea(wasql);
 end;
 SQLquery="";
 for j=1..rs do
  if ClearCrd_to:SQLquery=SQLquery+" DELETE FROM "+db_to+".[dbo]."+tablist[j];fi;
  if pos('@',tablist[j])<1 or SQLfilter='':
     SQLquery=SQLquery+" insert into "+db_to+".[dbo]."+tablist[j]+" select t0.* from "+db_from+".[dbo]."+tablist[j]+" t0"+if(SQLfilter<>''," where "+SQLfilter,"");
   | true:
     SQLquery=SQLquery+" insert into "+db_to+".[dbo]."+tablist[j]+" select t1.* from "+db_from+".[dbo]."+tablist[j]+" t1, "+realcrd+" t0 where t1.CARDUKEY=t0.UKEY"+if(SQLfilter<>''," and ("+SQLfilter+")","");
  fi;
 od;
 ExecuteSQL('',SQLquery,crd);



 end;


Proc UPDATE_REPLACE_SQL_in1crd(crd_in:s;crdsql:s;fields:s;что:s;начто:s;filter:s;UpdateTime:l);-- замена подстроки на подстроку по списку текстовых полей в 1 картотеке
-- crd_in = любая картотека доступная текущему пользователю для коннекта к серверу sql
-- crdsql = полное имя картотеки в которой проведутся замены
-- fields = список полей через пробел в которых проведутся замены
-- filter = пользовательский дополнительный фильтр sql
  var SQLquery:ls;
  var SQLquery1:ls;
  var z,t:i;
  var ss,SetUpdateTime:s;
     z=КоличествоСлов(fields,' ');
     for t=1..z do
      ss=ВыделитьСлово(t,fields,' ');
      SQLquery=SQLquery+if(t=1,"",",")+format("%0:s=REPLACE(%0:s,'%1:s','%2:s')" ,ss ,что ,начто);
      SQLquery1=SQLquery1+if(t=1,""," or ")+format("(%0:s like '%2:s%1:s%2:s')" ,ss ,что,"%");
     od;
     if UpdateTime:
        SetUpdateTime=' ,UpdateTime=DATEADD(second,1,getdate()) ';
        SQLquery=SQLquery+SetUpdateTime;
     fi;
     SQLquery1="("+SQLquery1+")";
     SQLquery="UPDATE "+crdsql+" SET "+SQLquery+" where "+SQLquery1;
     if filter<>'':
        filter=" and ("+filter+")";
        SQLquery=SQLquery+filter;
     fi;
     --message(SQLquery);
     ExecuteSQL('',SQLquery,crd_in);
end;




Proc DROP_TABLE_ListREPLACE_SQL(crd_in:s;db:s);--
-- crd_in = любая картотека доступная текущему пользователю для коннекта к серверу sql
-- db = база данных в которой будет удалена таблица ListREPLACE, если db=пустая строка - db берется как текущая для crd_in
  var SQLquery:ls;
     if db='':db=ВыделитьСлово(1,GetRealCardfileName(crd_in),'.');fi;
     SQLquery="IF OBJECT_ID ('"+db+".dbo.ListREPLACE', 'U') IS NOT NULL DROP TABLE "+db+".dbo.ListREPLACE";
     ExecuteSQL('',SQLquery,crd_in);
end;

Func CREATE_TABLE_ListREPLACE_SQL(crd_in:s;db:s):s;--Возвращает полное имя созданной картотеки
-- crd_in = любая картотека доступная текущему пользователю для коннекта к серверу sql
-- db = база данных в которой будет удалена таблица ListREPLACE
  var SQLquery:ls;
     if db='':db=ВыделитьСлово(1,GetRealCardfileName(crd_in),'.');fi;
     SQLquery="CREATE TABLE "+db+".dbo.ListREPLACE  (rep_from [varchar](256),rep_to [varchar](256))";
     ExecuteSQL('',SQLquery,crd_in);
     ^db+".dbo.ListREPLACE";
end;

var ListREPLACE_Что_менять[]:s;
var ListREPLACE_НаЧто_менять[]:s;


Proc INSERT_TABLE_ListREPLACE_SQL(crd_in:s;db:s;crd_sql:s);--
-- crd_in = любая картотека доступная текущему пользователю для коннекта к серверу sql
-- db = база данных в которой будет удалена таблица ListREPLACE
  var SQLquery:ls;
  var rs_old,rs_new:i;
var ssl:ls;
var ss:s;
var j,k,z,t:i;


  if db='':db=ВыделитьСлово(1,GetRealCardfileName(crd_in),'.');fi;
  if crd_sql<>'':crd_sql=db+".dbo.ListREPLACE";fi;
  SQLquery="INSERT INTO "+crd_sql+" (rep_from,rep_to) VALUES ";
  z=lengthofarray(Раб.SQL.ListREPLACE_Что_менять);
  if z<1:exit;fi;
  j=0;
  rs_old=COUNTinCRD(crd_in,crd_sql,'',false);--запоминаем количество записей до вставки
  rs_new=rs_old;
  showprogress(z,'Загрузка таблицы замен...');
  for k=1..z do
    progresspos(k);
    if ListREPLACE_Что_менять[k]<>'':
       j=j+1;
       ss=format("%2:s('%0:s','%1:s')",ListREPLACE_Что_менять[k],ListREPLACE_НаЧто_менять[k],if(j>1,',',''));
       ssl=ssl+ss;
       if j>400:
          ExecuteSQL('',SQLquery+ssl,crd_in);
          rs_new=rs_new+j;
          ssl='';j=0;
       fi;
    fi;
  od;
  if j>0:ExecuteSQL('',SQLquery+ssl,crd_in);fi;
  rs_new=rs_new+j;
  t=time;
  while rs_new>COUNTinCRD(crd_in,crd_sql,'',false) do
   for z=1..10000 do od;
   if time-t>10:break;fi;
  od;
  CloseProgress;
end;

Proc LoadListREPLACE(it:i);--
var k:i;
ClearVariable(Раб.SQL.ListREPLACE_Что_менять);
ClearVariable(Раб.SQL.ListREPLACE_НаЧто_менять);
for k=1..it do
  ListREPLACE_Что_менять  [k]=format("%0:0.10d",k);
  ListREPLACE_НаЧто_менять[k]=format("%0:0.10d",k);
od;
end;

func  GetCRD_UpdateStat(crd_tbb:s;crd_sql:s;filter:s;updatetime:s;count:i;show_msg:l):l; -- 1=добавлены новые или обновлены старые
 var rez:i;
 var waSQL:i;
 var lst:LS;
 var ll:L;
 var lnlst:i;
 lst='';lnlst=0;rez=-1;
 if updatetime='19000101 00:00:00.0' or count=0:
    if COUNTinCRD(crd_tbb,crd_sql,filter,show_msg)>0:
       rez=1;
       ^rez=1;
    fi;
 fi;

 lst='SELECT COUNT(*) as col from '+crd_sql+' WITH (NOLOCK)' ;
 if filter<>'':
    lst=lst+' WHERE '+filter+' and updatetime>'+updatetime;-- нашли новые записи
 fi;
    lst=lst+' union all ';

 lst='SELECT COUNT(*) as col from '+crd_sql+' WITH (NOLOCK)' ;
 if filter<>'':
    lst=lst+' WHERE '+filter+' and updatetime<='+updatetime; -- удалили в старых
 fi;

  if show_msg:ОкноВыполненияПоказать(2, "Запрос к базе данных...");fi;
  try
  waSQL=ОткрытьРабочуюОбластьSQL('',lst,crd_tbb);
   ll=true;
   if show_msg:ОкноВыполненияЗакрыть;fi;
  except
   ll=false;
   if show_msg:ОкноВыполненияЗакрыть;fi;
   Raise;
  end;
  if ll:
     if getfieldi(waSQL,1,'col')>0 or getfieldi(waSQL,2,'col')<>count: rez=1;fi;
--     if getfieldi(waSQL,2,'col')<>count:rez=1;fi;
     CloseWorkArea(waSQL);
  fi;
  ^rez=1;
end;

func  Get_ukey_LastUpdate(crd_tbb:s;crd_sql:s;filter:s;updatetime:s;show_msg:l):i; --

 if not(filter='' and(updatetime='19000101 00:00:00.0' or updatetime='')):
    if filter<>'' and (updatetime<>'19000101 00:00:00.0' and updatetime<>'') :
       filter=filter+' and updatetime>'+updatetime;
     | (updatetime<>'19000101 00:00:00.0' and updatetime<>''):
       filter=filter+' updatetime>'+updatetime;
    fi;
 fi;
 ^GetFieldIByAgrField(crd_tbb,crd_sql,'ukey','updatetime',filter,'max',show_msg);
end;



Func GetCardFieldS(crd_tbb:s;crd_sql:s;rec:i;field:s;show_msg:l):s;
^GetSelectFieldS('SELECT '+field+' from '+crd_sql+' WITH (NOLOCK) WHERE UKEY='+str(rec),crd_tbb,field,1,show_msg);
end;

Func GetCardFieldd(crd_tbb:s;crd_sql:s;rec:i;field:s;show_msg:l):d;
 if rec<1:^1.1.100;fi;
^GetSelectFieldd('SELECT '+field+' from '+crd_sql+' WITH (NOLOCK) WHERE UKEY='+str(rec),crd_tbb,field,1,show_msg);
end;



-------------------------------------------------------------------------------------------------------
---------------------------------------- Пакетное копирование данных из WorkAreaSql в WorkArea------------------
var FieldSin_Name     []:s;
var FieldSin_FieldOut []:s;
var FieldSin_Const    []:s;
var FieldNin_Name     []:s;
var FieldNin_FieldOut []:s;
var FieldNin_Const    []:n;
var FieldIin_Name     []:s;
var FieldIin_FieldOut []:s;
var FieldIin_Const    []:i;
var FieldDin_Name     []:s;
var FieldDin_FieldOut []:s;
var FieldDin_Const    []:d;
var FieldLin_Name     []:s;
var FieldLin_FieldOut []:s;
var FieldLin_Const    []:l;
Proc ClearFieldin;
    ClearVariable(Раб.sql.FieldSin_Name    );
    ClearVariable(Раб.sql.FieldSin_FieldOut);
    ClearVariable(Раб.sql.FieldSin_Const   );
    ClearVariable(Раб.sql.FieldNin_Name    );
    ClearVariable(Раб.sql.FieldNin_FieldOut);
    ClearVariable(Раб.sql.FieldNin_Const   );
    ClearVariable(Раб.sql.FieldIin_Name    );
    ClearVariable(Раб.sql.FieldIin_FieldOut);
    ClearVariable(Раб.sql.FieldIin_Const   );
    ClearVariable(Раб.sql.FieldDin_Name    );
    ClearVariable(Раб.sql.FieldDin_FieldOut);
    ClearVariable(Раб.sql.FieldDin_Const   );
    ClearVariable(Раб.sql.FieldLin_Name    );
    ClearVariable(Раб.sql.FieldLin_FieldOut);
    ClearVariable(Раб.sql.FieldLin_Const   );
end;
func PutFieldSin(wa:i;j:i;waout:i;jout:i;OnlyConst:l):i;
var z,k:i;
var val:s;
    z=lengthofarray(FieldSin_Name);
    for k=1..z do
      if FieldSin_FieldOut[k]='':
         val = FieldSin_Const[k];
       | true:
         if OnlyConst:^j;fi;
         val = GetFieldS(waout,jout,FieldSin_FieldOut[k]);
         if FieldSin_Const[k]<>'':--формат для строки
            val=format(FieldSin_Const[k],val);
         fi;
      fi;
      j=PutFieldS(wa,j,FieldSin_Name[k],val);
    od;
    ^j;
end;
func PutFieldNin(wa:i;j:i;waout:i;jout:i;OnlyConst:l):i;
var z,k:i;
var val:n;
    z=lengthofarray(FieldNin_Name);
    for k=1..z do
      if FieldNin_FieldOut[k]='':
         val = FieldNin_Const[k];
       | true:
         if OnlyConst:^j;fi;
         val = GetFieldN(waout,jout,FieldNin_FieldOut[k]);
      fi;
      j=PutFieldN(wa,j,FieldNin_Name[k],val);
    od;
    ^j;
end;
func PutFieldIin(wa:i;j:i;waout:i;jout:i;OnlyConst:l):i;
var z,k:i;
var val:I;
    z=lengthofarray(FieldIin_Name);
    for k=1..z do
      if FieldIin_FieldOut[k]='':
         val = FieldIin_Const[k];
       | true:
         if OnlyConst:^j;fi;
         val = GetFieldI(waout,jout,FieldIin_FieldOut[k]);
      fi;
      j=PutFieldI(wa,j,FieldIin_Name[k],val);
    od;
    ^j;
end;
func PutFieldDin(wa:i;j:i;waout:i;jout:i;OnlyConst:l):i;
var z,k:i;
var val:D;
    z=lengthofarray(FieldDin_Name);
    for k=1..z do
      if FieldDin_FieldOut[k]='':
         val = FieldDin_Const[k];
       | true:
         if OnlyConst:^j;fi;
         val = GetFieldD(waout,jout,FieldDin_FieldOut[k]);
      fi;
      j=PutFieldD(wa,j,FieldDin_Name[k],val);
    od;
    ^j;
end;
func PutFieldLin(wa:i;j:i;waout:i;jout:i;OnlyConst:l):i;
var z,k:i;
var val:L;
    z=lengthofarray(FieldLin_Name);
    for k=1..z do
      if FieldLin_FieldOut[k]='':
         val = FieldLin_Const[k];
       | true:
         if OnlyConst:^j;fi;
         val = GetFieldL(waout,jout,FieldLin_FieldOut[k]);
      fi;
      j=PutFieldL(wa,j,FieldLin_Name[k],val);
    od;
    ^j;
end;
func PutFieldin(wa:i;j:i;waout:i;jout:i;OnlyConst:l):i;
     j=PutFieldSin(wa,j,waout,jout,OnlyConst);
     j=PutFieldNin(wa,j,waout,jout,OnlyConst);
     j=PutFieldIin(wa,j,waout,jout,OnlyConst);
     j=PutFieldDin(wa,j,waout,jout,OnlyConst);
     j=PutFieldLin(wa,j,waout,jout,OnlyConst);
     ^j;
end;
Proc PutFieldSin_ini(j:i;f:s;c:s;o:s);
     FieldSin_Name[j]=f;
     FieldSin_Const[j]=c;
     FieldSin_FieldOut[j]=o;
end;
Proc PutFieldIin_ini(j:i;f:s;c:s;o:s);
     FieldIin_Name[j]=f;
     FieldIin_Const[j]=int(c);
     FieldIin_FieldOut[j]=o;
end;
Proc PutFieldDin_ini(j:i;f:s;c:s;o:s);
     FieldDin_Name[j]=f;
     FieldDin_Const[j]=StringToDate(c);
     FieldDin_FieldOut[j]=o;
end;
Proc PutFieldNin_ini(j:i;f:s;c:s;o:s);
var p:i;
     FieldNin_Name[j]=f;
     p=pos(',',c);
     if p>0:
        p=length(substr(c,p+1,255));
      | true:p=0;
     fi;
     FieldNin_Const[j]=round(c,p);
     FieldNin_FieldOut[j]=o;
end;
Proc PutFieldLin_ini(j:i;f:s;c:s;o:s);
     FieldLin_Name[j]=f;
     FieldLin_Const[j]=not (c='0' or up(SubStr(c,1,1))='F');
     FieldLin_FieldOut[j]=o;
end;

Proc PutFieldin_ini(ini:s;type:s);--ini= FieldSin_Name#FieldSin_Const|FieldSin_Name=FieldSin_FieldOut|
var  flds,j,k:i;
var  f,c,o,razd,CurrentWord:s;
     flds=WordsCount(ini,'|');
     type=up(type);
      if type='S':k=lengthofarray(FieldSin_Name);
       | type='I':k=lengthofarray(FieldIin_Name);
       | type='D':k=lengthofarray(FieldDin_Name);
       | type='N':k=lengthofarray(FieldNin_Name);
       | type='L':k=lengthofarray(FieldLin_Name);
      fi;
     for j=1..flds do
      CurrentWord=ExtractWord(j,ini,'|');
      if WordsCount(CurrentWord,'#')>1:razd='#';
       | WordsCount(CurrentWord,'@')>1:razd='@';
       | true:razd='=' ;
      fi;
      f=ExtractWord(1,CurrentWord,razd);
      if razd='#':c=ExtractWord(2,CurrentWord,razd);
       | razd='@':c=ExtractWord(2,CurrentWord,razd);o=ExtractWord(WordsCount(c,','),c,',');c=ExtractWords(1,WordsCount(c,',')-1,c,',');
       | true:o=ExtractWord(2,CurrentWord,razd);
      fi;
      k=k+1;
      if type='S':PutFieldSin_ini(k,f,c,o);
       | type='I':PutFieldIin_ini(k,f,c,o);
       | type='D':PutFieldDin_ini(k,f,c,o);
       | type='N':PutFieldNin_ini(k,f,c,o);
       | type='L':PutFieldLin_ini(k,f,c,o);
      fi;
      f='';c='';o='';
     od;
end;

Proc CopyWaSqlToWa(waSQL:i;wa:i;count_save:i;show_msg:l);
var count,rssql,z,j:i;
   count=count_save;
   try
     BeginChanging(wa,true);
       rssql=records(waSQL);
       if show_msg:ShowProgress(rssql,'Копирование данных...');fi;
       for z=1..rssql do
         if show_msg:ProgressPos(z);fi;
         count=count-1;
         j= InsertRecord(wa);
         j= PutFieldin(wa,j,waSQL,z,false);
         if count=0:
            count=count_save;
            if show_msg:ShowProgress(rssql,'Сохранение данных...');fi;
            EndChanging(wa);
            BeginChanging(wa,true);
            if show_msg:ShowProgress(rssql,'Копирование данных...');fi;
         fi;
       od;
     if show_msg:ShowProgress(rssql,'Сохранение данных...');fi;
     EndChanging(wa);
   except
     CancelChanging(wa);
   end;
   if show_msg:CloseProgress;fi;
end;

Proc CopySelectToWa(crd_tbb_for_sql:s;SelectSQL:ls;wa:i;count_save:i;show_msg:l);
var waSQL:i;
    waSQL = GetWorkAreaSQL(SelectSQL,crd_tbb_for_sql,show_msg);
    assert(waSQL>0,'Ошибка открытия рабочей области SQL');
    CopyWaSqlToWa(waSQL,wa,count_save,show_msg);
    CloseWorkArea(waSQL);
end;

Proc CopySelectToCrd(crd_tbb_for_sql:s;SelectSQL:ls;Crd:s;count_save:i;show_msg:l);
var wa:i;
    wa = OpenWorkArea(Crd,'');
    assert(wa>0,'Ошибка открытия рабочей области');
    CopySelectToWa(crd_tbb_for_sql,SelectSQL,wa,count_save,show_msg);
    CloseWorkArea(wa);
end;

Proc exampl_CopySelectToCrd;
var sls:ls;
var crd_tbb_for_sql:s;
   sls='Select * from '+GetRealCardfileName('КАРТОТЕКА1');
   crd_tbb_for_sql='ЛЮБАЯКАРТОТЕКА';
   Раб.sql.ClearFieldin;
   Раб.sql.PutFieldin_ini('МХЭ#М.Э.0001|МОЛ@МОЛ.%S,МОЛ_КОД|УЧРЕЖДЕНИЕ#НАШЕ УЧРЕЖДЕНИЕ','S');
   Раб.sql.PutFieldin_ini('СЧЕТНФА=СЧЕТНФА|НФА=НФА|FIRST_DATE=FIRST_DATE|МОЛИМЯ=МОЛИМЯ|НОМЕРБУМ=НОМЕРБУМ|ОКОФ=ОКОФ','S');
   Раб.sql.PutFieldin_ini('ПЕРВ_СТОИМ=ПЕРВ_СТОИМ|СТОИМ_ОТЧ=СТОИМ_ОТЧ|П_АМОРТ_НАКОП=П_АМОРТ_НАКОП|СНАЧ_ЭКСП=СНАЧ_ЭКСП','N');
   Раб.sql.PutFieldin_ini('НОМЕР=НОМЕР|АМОРТ_ГРУП=АМОРТ_ГРУП','I');
   Раб.sql.PutFieldin_ini('ДАТ_ВЭКСП=ДАТ_ВЭКСП|ДАТА_ИЗГ=ДАТА_ИЗГ','D');
   Раб.sql.PutFieldin_ini('ОПРИХ_ДАТА=ОПРИХ_ДАТА|LAST_DATE=LAST_DATE','D');
   Раб.sql.CopySelectToCrd(crd_tbb_for_sql,sls,'КАРТОТЕКА2',1000,true);-- пакетное копирование из КАРТОТЕКА1 в КАРТОТЕКА2 с сохранением по 1000 строк
   Раб.sql.ClearFieldin;
end;

---------------------------------------- Пакетное копирование данных из WorkAreaSql в WorkArea------------------
-------------------------------------------------------------------------------------------------------

Конец