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

Proc ШаблонПриОткрытии(l:l);
-- Message('Библиотека SQL^MРусспромоценка 2007г');
 Message('Библиотека SQL/ иерархическая^MТБ-БЮДЖЕТ 2015г');
 close;
end;
var bufs[]:s;
var gu[]:s;
var id[]:i;

--DECLARE @fff varchar(200)
----      SET @fff = '%анатоксин%'
--        SET @fff = '%_%'

--Select a.* ,b.name from (
--   Select distinct f.id fid ,a.*  from (

--           SELECT 0 id from MEDS_MAT_DB.DBO.REP_MED a0 WITH (NOLOCK) where a0.id=0  and (a0.name LIKE @fff)
--           union all
--           SELECT distinct a1.id from MEDS_MAT_DB.DBO.REP_MED a1 WITH (NOLOCK) where a1.parent_id=0  and (a1.name LIKE @fff)

--           union all
--           SELECT distinct a1.id from MEDS_MAT_DB.DBO.REP_MED a1 WITH (NOLOCK),MEDS_MAT_DB.DBO.REP_MED a2 WITH (NOLOCK) where a2.parent_id=a1.id AND a1.parent_id=0  and (a2.name LIKE @fff)
--           union all
--           SELECT distinct a2.id from MEDS_MAT_DB.DBO.REP_MED a1 WITH (NOLOCK),MEDS_MAT_DB.DBO.REP_MED a2 WITH (NOLOCK) where a2.parent_id=a1.id AND a1.parent_id=0  and (a2.name LIKE @fff)

--           union all
--           SELECT distinct a1.id from MEDS_MAT_DB.DBO.REP_MED a1 WITH (NOLOCK),MEDS_MAT_DB.DBO.REP_MED a2 WITH (NOLOCK),MEDS_MAT_DB.DBO.REP_MED a3 WITH (NOLOCK) where a3.parent_id=a2.id AND a2.parent_id=a1.id AND a1.parent_id=0  and (a3.name LIKE @fff)
--           union all
--           SELECT distinct a2.id from MEDS_MAT_DB.DBO.REP_MED a1 WITH (NOLOCK),MEDS_MAT_DB.DBO.REP_MED a2 WITH (NOLOCK),MEDS_MAT_DB.DBO.REP_MED a3 WITH (NOLOCK) where a3.parent_id=a2.id AND a2.parent_id=a1.id AND a1.parent_id=0  and (a3.name LIKE @fff)
--           union all
--           SELECT distinct a3.id from MEDS_MAT_DB.DBO.REP_MED a1 WITH (NOLOCK),MEDS_MAT_DB.DBO.REP_MED a2 WITH (NOLOCK),MEDS_MAT_DB.DBO.REP_MED a3 WITH (NOLOCK) where a3.parent_id=a2.id AND a2.parent_id=a1.id AND a1.parent_id=0  and (a3.name LIKE @fff)
--
--           union all
--           SELECT distinct a1.id from MEDS_MAT_DB.DBO.REP_MED a1 WITH (NOLOCK),MEDS_MAT_DB.DBO.REP_MED a2 WITH (NOLOCK),MEDS_MAT_DB.DBO.REP_MED a3 WITH (NOLOCK),MEDS_MAT_DB.DBO.REP_MED a4 WITH (NOLOCK) where a4.parent_id=a3.id AND a3.parent_id=a2.id AND a2.parent_id=a1.id AND a1.parent_id=0 and (a4.name LIKE @fff)
--           union all
--           SELECT distinct a2.id from MEDS_MAT_DB.DBO.REP_MED a1 WITH (NOLOCK),MEDS_MAT_DB.DBO.REP_MED a2 WITH (NOLOCK),MEDS_MAT_DB.DBO.REP_MED a3 WITH (NOLOCK),MEDS_MAT_DB.DBO.REP_MED a4 WITH (NOLOCK) where a4.parent_id=a3.id AND a3.parent_id=a2.id AND a2.parent_id=a1.id AND a1.parent_id=0 and (a4.name LIKE @fff)
--           union all
--           SELECT distinct a3.id from MEDS_MAT_DB.DBO.REP_MED a1 WITH (NOLOCK),MEDS_MAT_DB.DBO.REP_MED a2 WITH (NOLOCK),MEDS_MAT_DB.DBO.REP_MED a3 WITH (NOLOCK),MEDS_MAT_DB.DBO.REP_MED a4 WITH (NOLOCK) where a4.parent_id=a3.id AND a3.parent_id=a2.id AND a2.parent_id=a1.id AND a1.parent_id=0 and (a4.name LIKE @fff)
--           union all
--           SELECT distinct a4.id from MEDS_MAT_DB.DBO.REP_MED a1 WITH (NOLOCK),MEDS_MAT_DB.DBO.REP_MED a2 WITH (NOLOCK),MEDS_MAT_DB.DBO.REP_MED a3 WITH (NOLOCK),MEDS_MAT_DB.DBO.REP_MED a4 WITH (NOLOCK) where a4.parent_id=a3.id AND a3.parent_id=a2.id AND a2.parent_id=a1.id AND a1.parent_id=0 and (a4.name LIKE @fff)

--           ) f
--   left join
--  (SELECT '0' GU,0 id,-1 a1,-1 a2,-1 a3,-1 a4
--   union all
--   SELECT '0.'+cast(a1.id as varchar)GU,a1.id,a1.id a1,-1 a2,-1 a3,-1 a4 from MEDS_MAT_DB.DBO.REP_MED a1 WITH (NOLOCK) where a1.parent_id=0
--   union all
--   SELECT '0.'+cast(a1.id as varchar)+'.'+cast(a2.id as varchar)GU,a2.id,a1.id a1,a2.id a2,-1 a3,-1 a4 from MEDS_MAT_DB.DBO.REP_MED a1 WITH (NOLOCK),MEDS_MAT_DB.DBO.REP_MED a2 WITH (NOLOCK) where a2.parent_id=a1.id AND a1.parent_id=0
--   union all
--   SELECT '0.'+cast(a1.id as varchar)+'.'+cast(a2.id as varchar)+'.'+cast(a3.id as varchar)GU,a3.id,a1.id a1,a2.id a2,a3.id a3,-1 a4 from MEDS_MAT_DB.DBO.REP_MED a1 WITH (NOLOCK),MEDS_MAT_DB.DBO.REP_MED a2 WITH (NOLOCK),MEDS_MAT_DB.DBO.REP_MED a3 WITH (NOLOCK) where a3.parent_id=a2.id AND a2.parent_id=a1.id AND a1.parent_id=0
--   union all
--   SELECT '0.'+cast(a1.id as varchar)+'.'+cast(a2.id as varchar)+'.'+cast(a3.id as varchar)+'.'+cast(a4.id as varchar)GU,a4.id,a1.id a1,a2.id a2,a3.id a3,a4.id a4 from MEDS_MAT_DB.DBO.REP_MED a1 WITH (NOLOCK),MEDS_MAT_DB.DBO.REP_MED a2 WITH (NOLOCK),MEDS_MAT_DB.DBO.REP_MED a3 WITH (NOLOCK),MEDS_MAT_DB.DBO.REP_MED a4 WITH (NOLOCK) where a4.parent_id=a3.id AND a3.parent_id=a2.id AND a2.parent_id=a1.id AND a1.parent_id=0
--   ) a
----   on a.id in (f.a1,f.a2,f.a3,f.a4)
--   on a.id=f.id
--   --Where ((name LIKE '%анатоксин%'))  and  f.id in (0,a.a1,a.a2,a.a3,a.a4))
--   ) a,MEDS_MAT_DB.DBO.REP_MED b  WITH (NOLOCK) where b.id=a.id order by a.GU

---------------------------------------------------------------------------------------------------------------------------------
----------- ================ Служебные функции для SelectAsGROUPDOC_filter_rez_no_order ================ ------------------------
func SelectAsGROUPDOC_level_From(crdsql:s;root:i;level:i;AsUkey:s;AsGroupDoc:s;filter:Ls):Ls;
var result:Ls;
var format_level:s;
var format_level_filter:s;
var format_level_filter1:s;
var j:i;
  if level<0:^'';fi;
  format_level = "%0:s a%1:d WITH (NOLOCK)";
  format_level_filter = format_level;
  if filter<>'':
     format_level_filter = "(select * from "+format_level+" where ";
     format_level_filter1= ") a%1:d";
  fi;
  if level>1:
     result = format(format_level, crdsql, 1);
     for j=2..level-1 do
       result=result+','+format(format_level, crdsql, j);
     od;
     result=result+',';
  fi;
  result=result+format(format_level_filter, crdsql, level)+filter+format(format_level_filter1, crdsql, level);
 ^result;
end;

func SelectAsGROUPDOC_level_Where(crdsql:s;root:i;level:i;AsUkey:s;AsGroupDoc:s;filter:Ls):Ls;
var result:Ls;
var format_level,format_level_root:s;
var j,k:i;
  if level<0:^'';fi;
  format_level_root = "a%3:d.%0:s=%2:d";   --  AsUkey,AsGroupDoc,root,j,j-1
  format_level      = "a%3:d.%1:s=a%4:d.%0:s";
  if level = 0:result = format(format_level_root,AsUkey,AsGroupDoc,root,0);
   | true     :result = format(format_level_root,AsGroupDoc,AsUkey,root,1);
  fi;
  for j=2..level do
      result = format(format_level,AsUkey,AsGroupDoc,root,j,j-1)+' AND '+result;
  od;
 ^result;
end;

func format_cast(AsUkey:s;j:i;root:i):s;
  if j<0:^'';fi;
  if j=0:^"'"+str(root)+"'";fi;
  ^format("cast(a%1:d.%0:s as varchar)",AsUkey,j);
end;

func SelectAsGROUPDOC_level_GU_a(crdsql:s;root:i;level:i;AsUkey:s;AsGroupDoc:s;levelMax:i):Ls;
var result:Ls;
var format_a,a:s;
var j,k:i;

  if level<0:^'';fi;

  result = format_cast(AsUkey,0,root);
  format_a="a%1:d.%0:s a%1:d";
  if level=0:
     a=str(root)+' '+AsUkey;
   | true:
     a='a'+str(level)+'.'+AsUkey;
  fi;
  for j=1..level do
    result  = result   + "+'.'+"+format_cast(AsUkey,j,root);
    a= a + ','+format(format_a,AsUkey,j);
  od;
  format_a="-1 a%1:d";
  for j=level+1..levelMax do
    a= a + ','+format(format_a,AsUkey,j);
  od;
  result = result+' GU,'+ a;
 ^result;
end;

func SelectAsGROUPDOC_level_GU(crdsql:s;root:i;level:i;AsUkey:s;AsGroupDoc:s;levelMax:i):Ls;
var result:Ls;
var format_a,a:s;
var j,k:i;
  if level<0:^'';fi;
  result = 'SELECT '+SelectAsGROUPDOC_level_GU_a(crdsql,root,level,AsUkey,AsGroupDoc,levelMax);
  if level = 0:^result; fi;
  result = result + ' from '+ SelectAsGROUPDOC_level_From(crdsql,root,level,AsUkey,AsGroupDoc,'')+' where '+SelectAsGROUPDOC_level_Where(crdsql,root,level,AsUkey,AsGroupDoc,'');
 ^result;
end;

func SelectAsGROUPDOC_level_GU_all(crdsql:s;root:i;level:i;AsUkey:s;AsGroupDoc:s):Ls;
var result:Ls;
var result0:Ls;
var format_level:s;
var j:i;
  result = SelectAsGROUPDOC_level_GU(crdsql,root,0,AsUkey,AsGroupDoc,level);
  for j=1..level do
      result = result + ' union all ' + SelectAsGROUPDOC_level_GU(crdsql,root,j,AsUkey,AsGroupDoc,level);
  od;
 ^result;
end;


func SelectAsGROUPDOC_level_distinct(crdsql:s;root:i;level:i;AsUkey:s;AsGroupDoc:s;filter:Ls):Ls;
var result:Ls;
var result0:Ls;
var format_level:s;
var j:i;
  if level<0:^'';fi;
  result0 =' from '+SelectAsGROUPDOC_level_From(crdsql,root,level,AsUkey,AsGroupDoc,filter)+' where '+SelectAsGROUPDOC_level_Where(crdsql,root,level,AsUkey,AsGroupDoc,filter);
  format_level = 'SELECT distinct a%0:d.%1:s';
  if level = 0:result = 'SELECT '+str(root)+' '+AsUkey+result0;
   | true     :result = format(format_level,1,AsUkey)+result0;
  fi;
  for j=2..level do
      result = result + ' union all ' + format(format_level,j,AsUkey)+result0;
  od;
 ^result;
end;

func SelectAsGROUPDOC_level_distinct_all(crdsql:s;root:i;level:i;AsUkey:s;AsGroupDoc:s;filter:Ls):Ls;
var result:Ls;
var result0:Ls;
var format_level:s;
var j:i;
  result = SelectAsGROUPDOC_level_distinct(crdsql,root,0,AsUkey,AsGroupDoc,filter);
  for j=1..level do
      result = result + ' union all ' + SelectAsGROUPDOC_level_distinct(crdsql,root,j,AsUkey,AsGroupDoc,filter);
  od;
 ^result;
end;

----------- ================ Служебные функции для SelectAsGROUPDOC_filter_rez_no_order ================ ------------------------
---------------------------------------------------------------------------------------------------------------------------------


func SelectAsGROUPDOC_level(crdsql:s;root:i;level:i;AsUkey:s;AsGroupDoc:s):Ls;-- готовый запрос на иерархическую картотеку
-- запрос возвращаяет только 2последний0 уровень вложенности!
-- возврат 2-ух столбцов
-- UKEY:integer= все записи входящие в куст root
-- GU  :string =цепочка по ссылкам UKEY.UKEY.UKEY где последний UKEY=UKEY из первого столбца, а первый =root

-- level=уровень вложения (0=root,1=все что входит в root,2=все что является потомком выборки для level=1)
var select0,select1,select2:s;
var lsta:ls;
var j:i;
 select0="select "+str(root)+" "+AsUkey+", '"+str(root)+"' GU";
 select1="select b."+AsUkey+" ,a.GU+'.'+cast(b."+AsUkey+" as varchar) GU from (";

 lsta=select0;
 select2=") a,"+crdsql+" b  WITH (NOLOCK) where b."+AsGroupDoc+"=a."+AsUkey;

 for j=1..level do
   lsta=select1+lsta+select2;
 od;

^lsta;
end;


func SelectGROUPDOC_level(crdsql:s;root:i;level:i):Ls;-- готовый запрос на иерархическую картотеку ТБ
  ^SelectAsGROUPDOC_level(crdsql,root,level,'UKEY','GROUPDOC');
end;

func SelectAsGROUPDOC(crdsql:s;root:i;level:i;AsUkey:s;AsGroupDoc:s):Ls;-- готовый запрос на иерархическую картотеку
-- запрос возвращаяет 2весь0 куст!
-- возврат 2-ух столбцов
-- 1) UKEY:integer= все записи входящие в куст root
-- 2) GU  :string =цепочка по ссылкам root.GROUPDOC.GROUPDOC...GROUPDOC.UKEY где последний UKEY=UKEY из первого столбца, а первый =root

-- level=уровень вложения (0=root,1=все что входит в root+результат где level=0,2=все что является потомком выборки для level=1+результат где level=1)
var lst:ls;
var j:i;
 lst=SelectAsGROUPDOC_level(crdsql,root,0,AsUkey,AsGroupDoc);
 for j=1..level do
 lst=lst+" union all "+SelectAsGROUPDOC_level(crdsql,root,j,AsUkey,AsGroupDoc);
 od;
^lst;
end;

func SelectGROUPDOC(crdsql:s;root:i;level:i):Ls;-- готовый запрос на иерархическую картотеку ТБ 
  ^SelectAsGROUPDOC(crdsql,root,level,'UKEY','GROUPDOC');
end;


func SelectAsGROUPDOC_filter_rez_no_order(crdsql:s;root:i;level:i;filter:Ls;AsUkey:s;AsGroupDoc:s):Ls;-- готовый запрос на иерархическую картотеку с фильтром
-- запрос возвращаяет весь куст!
-- возврат 2-ух столбцов
-- 1) UKEY:integer= все записи входящие в куст root
-- 2) GU  :string =цепочка по ссылкам root.GROUPDOC.GROUPDOC...GROUPDOC.UKEY где последний UKEY=UKEY из первого столбца, а первый =root
-- level=уровень вложения (0=root,1=все что входит в root+результат где level=0,2=все что является потомком выборки для level=1+результат где level=1)
-- отбираются все узлы ветви, если любой из ее узлов попадает в фильтр
var lst:ls;
var j:i;
var ss:s;
if filter<>'':
   lst='Select a.* from ('+SelectAsGROUPDOC_level_distinct_all(crdsql,root,level,AsUkey,AsGroupDoc,filter)+')f left join (';
   lst=lst+SelectAsGROUPDOC_level_GU_all(crdsql,root,level,AsUkey,AsGroupDoc)+') a on a.'+AsUkey+'=f.'+AsUkey;
 | true:
   lst=SelectAsGROUPDOC_level_GU_all(crdsql,root,level,AsUkey,AsGroupDoc);
fi;
^lst;
end;


func SelectGROUPDOC_filter_rez_no_order(crdsql:s;root:i;level:i;filter:Ls):Ls;-- готовый запрос на иерархическую картотеку ТБ с фильтром
  ^SelectAsGROUPDOC_filter_rez_no_order(crdsql,root,level,filter,'UKEY','GROUPDOC');
end;

func SelectAsGROUPDOC_filter(crdsql:s;root:i;level:i;filter:ls;fields:s;AsUkey:s;AsGroupDoc:s):Ls;-- готовый запрос на иерархическую картотеку с фильтром (фильтром-sql)
-- запрос возвращаяет весь куст!
-- возврат 2-ух обязательных столбцов + столбцы из fields
-- 1) UKEY:integer= все записи входящие в куст root
-- 2) GU  :string =цепочка по ссылкам root.GROUPDOC.GROUPDOC...GROUPDOC.UKEY где последний UKEY=UKEY из первого столбца, а первый =root
-- 3) fields=список полей через запятую возвращаемых дополнительно
-- level=уровень вложения (0=root,1=все что входит в root+результат где level=0,2=все что является потомком выборки для level=1+результат где level=1)
var lst:ls;
var j:i;
var ss:s;
 if fields='':fields="GU,b."+AsUkey;
  | true:
    if not WordInString(AsUkey,fields,","):fields="b."+AsUkey+","+fields;fi;
    if not WordInString("GU",fields,","  ):fields="GU,"+fields;fi;
 fi;
 lst=SelectAsGROUPDOC_filter_rez_no_order(crdsql,root,level,filter,AsUkey,AsGroupDoc);
 lst="Select "+fields+" from ("+lst+") a,"+crdsql+" b  WITH (NOLOCK) where b."+AsUkey+"=a."+AsUkey;
 lst=lst+" order by GU,b."+AsUkey;
^lst;
end;

func SelectGROUPDOC_filter(crdsql:s;root:i;level:i;filter:ls;fields:s):Ls;-- готовый запрос на иерархическую картотеку ТБ
  ^SelectAsGROUPDOC_filter(crdsql,root,level,filter,fields,'UKEY','GROUPDOC');
end;

-------------------------------------------------------------------------------------------------------
---------------------------------------- тестовая разработка ------------------------------------------
func SelectGROUPDOC_filter_join(crdsql_as_a:s;root:i;level:i;filter:ls;fields:s;crdsql_join_as_b:s;where_join:s):Ls;-- готовый запрос на иерархическую картотеку ТБ
-- запрос возвращаяет весь куст!
-- возврат 2-ух столбцов
-- 1) UKEY:integer= все записи входящие в куст root
-- 2) GU  :string =цепочка по ссылкам root.GROUPDOC.GROUPDOC...GROUPDOC.UKEY где последний UKEY=UKEY из первого столбца, а первый =root
-- 3) fields=список полей через запятую
-- level=уровень вложения (0=root,1=все что входит в root+результат где level=0,2=все что является потомком выборки для level=1+результат где level=1)
var lst:ls;
var j:i;
var ss:s;
 if fields='':fields="GU,b.UKEY,a.UKEY a_UKEY";
  | true:
    if not WordInString("ukey",fields,","):fields="b.ukey,a.UKEY a_UKEY,"+fields;fi;
    if not WordInString("GU",fields,","  ):fields="GU,"+fields;fi;
 fi;
 lst=SelectGROUPDOC_filter_rez_no_order(crdsql_as_a,root,level,filter);
 lst="Select "+fields+" from ("+lst+") a,"+crdsql_join_as_b+" b  WITH (NOLOCK)"
    +if(where_join<>'',"where "+where_join,"");
 lst=lst+" order by b.UKEY";
^lst;
end;

func SelectGROUPDOC_filter_join0(crdsql_as_a:s;root:i;level:i;filter:ls;fields:s;crdsql_join_as_b:s;where_join:s):Ls;-- готовый запрос на иерархическую картотеку ТБ
var lst:ls;
var j:i;
var ss:s;
 if fields<>'':fields=","+fields;
 fi;
 lst=SelectGROUPDOC_filter_rez_no_order(crdsql_as_a,root,level,filter);
 lst="Select a.GU+'.'+ltrim(str(b.UKEY)) GU,b.UKEY "+fields+" from ("+lst+") a,"+crdsql_join_as_b+" b  WITH (NOLOCK)"
    +if(where_join<>'',"where "+where_join,"");
^lst;
end;

func SelectGROUPDOC_filter_join1(crdsql_as_a:s;root:i;level:i;filter:ls;fields:s;crdsql_join_as_b:s;where_join:s;fields_b:s):Ls;-- готовый запрос на иерархическую картотеку ТБ
var lst:ls;
var j:i;
var ss:s;

 if fields='':fields="GU,b.UKEY";
  | true:
    if not WordInString("ukey",fields,","):fields="b.ukey,"+fields;fi;
    if not WordInString("GU",fields,","  ):fields="GU,"+fields;fi;
 fi;
 lst=SelectGROUPDOC_filter_join0(crdsql_as_a,root,level,filter,fields_b,crdsql_join_as_b,where_join);
 lst=SelectGROUPDOC_filter_rez_no_order(crdsql_as_a,root,level,filter);
 lst="Select "+fields+" from ("+lst+") a,"+crdsql_as_a+" b  WITH (NOLOCK) where b.ukey=a.ukey";
 lst=lst+" union all "+SelectGROUPDOC_filter_join0(crdsql_as_a,root,level,filter,fields_b,crdsql_join_as_b,where_join);
 lst=lst+" order by GU,UKEY";
^lst;

end;

---------------------------------------- тестовая разработка ------------------------------------------
-------------------------------------------------------------------------------------------------------


func GetMaxLevelAsGROUPDOC(crdsql:s;root:i;crd_tbb:s;AsUkey:s;AsGroupDoc:s):i; -- подсчет уровней вложенности относительно узла root
var rez:i;
var ll:l;
var select0,select1,select2:s;
var lsta:ls;
var j,level:i;
 select0="select "+str(root)+" "+AsUkey;
 select1="select b."+AsUkey+" from (";
 select2=") a,"+crdsql+" b WITH (NOLOCK) where b."+AsGroupDoc+"=a."+AsUkey;
 lsta=select0;
 for j=0..19 do
 lsta=select1+lsta+select2;
-- ll=1=Раб.SQL.GetSelectFieldi('select (case when EXISTS ('+lsta+')  then 1 else 0 end) exst',crd_tbb,'exst',1,true);
 ll=Раб.SQL.GetSelectFieldl('select (case when EXISTS ('+lsta+')  then 1 else 0 end) exst',crd_tbb,'exst',1,true);
 if not ll: ^j;
   break;
 fi;
 od;
^rez;
end;


func GetMaxLevelGROUPDOC(crdsql:s;root:i;crd_tbb:s):i; -- подсчет уровней вложенности относительно узла root, для картотеки ТБ
  ^GetMaxLevelAsGROUPDOC(crdsql,root,crd_tbb,'UKEY','GROUPDOC');
end;

Proc CopySubTreeInNodeTBCard(crd_tbb_for_sql:s; crdsql:s; FilterToSQL:ls; root:i; AsUkey:s; AsGroupDoc:s;fieldsfrom:s; To_crd_tbb:s;To_crd_tbb_node:i;show_msg:l);
var lst:ls;
var waSQL,wa, maxukey, maxleveltree,rssql,pred,j,z:i;
    ShowProgress(rssql,'Подготовка данных...');
    maxukey = Раб.sql.GetAgrFieldI(To_crd_tbb,GetRealCardfileName(To_crd_tbb),'UKEY','','max',false) + 1;
    maxleveltree = GetMaxLevelAsGROUPDOC(crdsql,root,crd_tbb_for_sql,AsUkey,AsGroupDoc);
    lst= SelectAsGROUPDOC_filter(crdsql,root,maxleveltree,FilterToSQL,fieldsfrom,AsUkey,AsGroupDoc);
    ShowProgress(rssql,'Получение данных...');
    waSQL = Раб.sql.GetWorkAreaSQL(lst,crd_tbb_for_sql,show_msg);
    assert(waSQL>0,'Ошибка открытия рабочей области SQL');
    rssql=records(waSQL);
    ClearVariable(Раб.sql.HA.gu);
    try
      z=1;
      wa=openworkarea(To_crd_tbb,'');
        try
          BeginChanging(wa,true);
            pred=To_crd_tbb_node;
              if To_crd_tbb_node<>0:
               if not RecordExists('РПО_ОТЧЕТЫ_СТРОКИ',IntegerToRecord(To_crd_tbb_node)):
                 j= InsertRecordByKey(wa,IntegerToRecord(To_crd_tbb_node));
                 j= Раб.SQL.PutFieldin(wa,j,waSQL,0,true);
                 j=PutFieldI(wa,j,'GroupAttr',-1);
               fi;
              fi;
            ShowProgress(rssql,'Перенос данных...');
            for z=1..rssql do
              ProgressPos(z);
              j= InsertRecordByKey(wa,IntegerToRecord(maxukey+z));
              gu[z]=GetFieldS(waSQL,z,'gu');
              j= Раб.SQL.PutFieldin(wa,j,waSQL,z,false);
              pred=WordsCount(gu[z],'.');
              if pred<2:pred=To_crd_tbb_node;
               | true:
                 pred=SearchInArray(gu,ExtractWordS(1,pred-1,gu[z],'.'),true);
                 if pred<1:pred=To_crd_tbb_node;
                  | true:pred=pred+maxukey;
                 fi;
              fi;
              j=PutFieldR(wa,j,'GROUPDOC',IntegerToRecord(pred));
              j=PutFieldI(wa,j,'GroupAttr',-1);
            od;
          ShowProgress(rssql,'Сохранение данных...');
          EndChanging(wa);
        except
          CancelChanging(wa);
        end;
      closeworkarea(wa);
    except
    end;
    CloseProgress;
    CloseWorkArea(waSQL);
    ClearVariable(Раб.sql.HA.gu);
end;


Proc CopySubTreeInNodeTBCard_Пример;
var AsGroupDoc, AsUkey, ff, crdsql, crd:s;
var FilterToSQL:ls;
var nodeto,nodefrom:i;
   exit;
   crdsql='MEDS_MAT_DB.DBO.REP_MED'; -- полное имя картотеки в экземпляре SQL Server-а (откуда выбираем данные для копирования)
   AsGroupDoc='parent_id';-- аналог GroupDoc в картотеке crdsql
   AsUkey    ='id';       -- аналог Ukey в картотеке crdsql
   ff='стол стул';
   ff=РАБ.СТР.WordsForLike(ff,' ','**');
   FilterToSQL=Раб.sql.WordsAsLike(ff,'name',' ','or');-- получили фильтр для поля 'name' в картотеке crdsql, аналог= match(name,'*стол*') or match(name,'*стул*')
   crd='РПО_ОТЧЕТЫ_СТРОКИ';-- картотека в ТБ, 'куда' добавляем новый куст
   nodeto=1;  -- ukey в картотеке РПО_ОТЧЕТЫ_СТРОКИ, на который будет ссылаться весь куст (если такой записи нет, то она будет создана)
   nodefrom=0;-- выбираем всю внешнюю картотеку как куст (если не 0, то куст ссылающийся на данный узел, не включая его)
   Раб.sql.ClearFieldin;
   Раб.sql.PutFieldin_ini('КОД3=gu|ИМЯ=name|РАЗРАБОТЧИК#ТББ','s'); -- прописываем соответствие полей(констант) для строкового типа
   Раб.sql.PutFieldin_ini('ВЫВОД#true','l');  -- прописываем соответствие полей(констант) для  логического типа
   Раб.sql.PutFieldin_ini('NN#'+AsUkey,'i'); -- прописываем соответствие полей(констант) для  целочисленного типа
   Раб.sql.HA.CopySubTreeInNodeTBCard(crd,crdsql,FilterToSQL,nodefrom,AsUkey,AsGroupDoc,'name',crd,nodeto,false);-- копируем данные с новыми UKEY больше максимального значения UKEY в РПО_ОТЧЕТЫ_СТРОКИ
   Раб.sql.ClearFieldin;
end;

Конец

