<?xml version="1.0" encoding="windows-1251"?>
<registry>
<script type="abl" exec="">
включить "\библиотеки\libru.lib";
включить "\библиотеки\Documents.lib";
включить "\Библиотеки\Reports.lib";
включить '\Библиотеки\output.lib';
включить "\Макросы\Вспомогательные.abl";
включить "\Библиотеки\SysUtils.lib";
включить "\библиотеки\Layers.lib";
включить "\Макросы\слои\ПоддержкаСлойницы.abl";

ПреобразованиеВБуквенныйКлассификатор;


константы
  алиасПодключенийКБазамДанных = "Платформа.БазыДанных.Подключения";
  алиасПользователейБД         = "Платформа.БазыДанных.Пользователи";
  аЗанятыеПоля                 = "Платформа.СтроковыйЦСР.Поля";
  
  аБлоки = "Платформа.ДескрипторыБлоков";
  аРасширения = "Платформа.ДескрипторыБлоков.РасширенияКомпонентов"; //РасширенияКомпонентов
  аОбработчики = "Платформа.Компоненты.ОписаниеПодключенийОбработчиков"; //ПодключениеОбработчиков
  аПередача = "Платформа.Компоненты.ОписаниеПередачиПараметров"; //ПередачаПараметров
  аКонтроллеры = "Платформа.Контроллеры.ОписаниеКонтроллеров"; //Контроллер 
  
  аСлои = "Платформа.Слои.ОписанияСлоев";
  
  КонтроллерыДобавленияПоля = "Платформа.Слои.ИзменитьАтрибутыКолонки,Платформа.Слои.ЗадатьОписаниеПоля";
переменные
  ПараметрыПодключения: Строка;
  МенеджерСлоев: ILayersMan;
  

функция СформироватьАлиасБД(ИмяБазы: строка; ПараметрыПодключения: строка): целое;
переменные
  СлойБД, СлойПользователей: ILayer;
  ДанныеБД, ДанныеПользователей: СтатическиеДанные;
  ПараметрыБД: Текст;
  ИмяДрайвера, ИмяСервера, Схема, Логин, Пароль: строка;
  Данные: СтатическиеДанные;
начало
  ПараметрыПодключения := "";
  если IsOracle() тогда
  начало
    //путь к базе получаем из слоя "Базы данных"
    СлойБД := ПолучитьМенеджерСлоев.CreateLayerByAlias(АлиасПодключенийКБазамДанных);
    СлойБД.SelectData(nil);
    ДанныеБД := СлойБД.LayerData;
    ДанныеБД.Локализовать("ИмяБазыДанных", ИмяБазы, 0);
    ИмяДрайвера := ДанныеБД.ПолеПоИмени("ИмяДрайвера").КакСтрока;  
    ПараметрыБД := СоздатьТекст;
    попытка
      ПараметрыБД.РазделенноеЗначение := ДанныеБД.ПолеПоИмени("ПараметрыБД").КакСтрока;
      ИмяСервера := ПараметрыБД.ЗначениеПараметра("AliasName");
      Схема := '';
      если ДанныеБД.ПолеПоИмени("ТипБазыДанных").КакСтрока = "Oracle" тогда
        Схема := 'schema='+ПараметрыБД.ЗначениеПараметра("Schema"); 
    обязательно
      УдалитьОбъект(ПараметрыБД);
    конец;
    ПараметрыПодключения := Формат("DatabaseName=%s"#13#10"DriverName=%s"#13#10"SERVER NAME=%s"#13#10"%s",
                                                      ИмяБазы, ИмяДрайвера, ИмяСервера, Схема);
    
    //логин и пароль хранятся в слое "Пользователи баз данных"
    СлойПользователей := ПолучитьМенеджерСлоев.CreateLayerByAlias(АлиасПользователейБД);
    СлойПользователей.SelectData(nil);
    ДанныеПользователей := СлойПользователей.LayerData;   
    ДанныеПользователей.Фильтр := "ИмяПользователяЛокальное='"+ТекущийПользователь+"'";
    если не ДанныеПользователей.Локализовать("ИмяБазыДанных", ИмяБазы, 0) тогда
      ВызватьОшибку("Не найдены параметры подключения к базе данных с именем '" + ИмяБазы +"' !");  
    Логин := ДанныеПользователей.ПолеПоИмени("ИмяПользователяУдаленное").КакСтрока;
    Пароль := ДанныеПользователей.ПолеПоИмени("ПарольУдаленный").КакСтрока;
    ПараметрыПодключения := Формат("%s"#13#10"USER NAME=%s"#13#10"PASSWORD=%s", ПараметрыПодключения, Логин, Пароль);
  
    попытка
      Данные := СоздатьСтатическиеДанные;
      Данные.СоединитьБД(ПараметрыПодключения);
      Данные.Запрос := "[PumpData]{select count(*) from LayerData}";
      Данные.Открыть;
      результат := Данные.RecordCount &gt; 0;
    неудача
      результат := нет;
      ПараметрыПодключения := ПоследняяОшибка;
    конец;
  конец
  иначе
    результат := да;

конец;
      
  // Комментарий
  функция ЕслиЗначение(Условие: целое; Val1, Val2: строка): строка;
  начало
    если Условие тогда
      результат := Val1
    иначе
      результат := Val2;
  конец;

  // Есть ли поле в LayerData
  функция СуществуетПоле(Имя: строка): целое;
  переменные
    Данные: СтатическиеДанные;
  начало
    Данные := СоздатьСтатическиеДанные;
    если IsOracle() тогда
    начало
      Данные.СоединитьБД(ПараметрыПодключения);
      Данные.Запрос := "[PumpData]{select count(*) from User_Tab_Columns where Table_Name = 'LAYERDATA' and Column_Name = '@FieldName'}";
    конец
    иначе
    начало
      Данные.СоединитьБД;
      Данные.Запрос := "[PumpData]{select count(*) from rdb\$Relation_Fields where rdb\$Relation_Name = 'LAYERDATA' and rdb\$Field_Name = '@FieldName'}";
    конец;
    Данные.Параметр("FieldName") := Имя;
    Данные.Открыть;
    результат := Данные.Поля(0).КакЦелое;
  конец;
  
  // Комментарий
  функция СуществуетСвободноеСтроковоеПоле(СтроковыеПоляСлоев: IVariables; Алиас: строка; ИмяПоля: строка): целое;
  переменные
    Данные, Поля: СтатическиеДанные;
    к, Необходимо: целое;
    СтроковыеПоля, НомерПоля: строка;
    Слой: ILayer;
  начало
    результат := нет; ИмяПоля := '';
    если СтроковыеПоляСлоев.ПараметрСуществует(Алиас) тогда
    начало
      СтроковыеПоля := СтроковыеПоляСлоев.Значение(Алиас);
      Необходимо := да;
    конец
    иначе
    начало
      попытка
        Слой := МенеджерСлоев.CreateLayerByAlias(Алиас);
        Необходимо := Слой.Description.Params('TableName') = 'LayerData' или Слой.Description.Params('TableName') = 'CalcData';
        Поля := Слой.Description.Fields.Data;
      неудача
        Поля := СоздатьСтатическиеДанные;
        Поля.СоединитьБД;
        Поля.Запрос := "[PumpData]{select lf.*, l.TableName TableName from LayerFields lf, Layers l where lf.RecordIndex = l.ID and l.Alias = '@LayerAlias'}";
        Поля.Параметр("LayerAlias") := Алиас;
        Поля.Открыть;
        Необходимо := Поля.Поле('TableName').КакСтрока = 'LayerData' или Поля.Поле('TableName').КакСтрока = 'CalcData';
      конец;
      если Необходимо тогда
      начало
        Данные := СоздатьСтатическиеДанные;
        Данные.ДобавитьСтроковоеПоле('DBName', 4096);
        Данные.ДобавитьЦелоеПоле('Flag');
        Данные.Открыть;
        Данные.Группировать(Поля, "keys=*;DBName=DBName;Flag=DBName like 'STRFIELD%'");
        Данные.Filter := 'Flag=1';
        Данные.Filtered := да;
        если Данные.ВНачале и Данные.ВКонце тогда
        начало
          ИмяПоля := 'STRFIELD00';
          результат := да;
        конец
        иначе
        начало
          ВнутренняяГруппировка(Данные, 'keys=;DBName=sum(DBName + ",")', да);
          СтроковыеПоля := Данные.Поле('DBName').КакСтрока;
        конец;
      конец;
    конец;
    
    
    если результат тогда
      СтроковыеПоляСлоев.Значение(Алиас) := ИмяПоля
    иначе
      если Необходимо тогда  
        от к := 0 до 25 делать
        начало
          НомерПоля := ЦелоеВСтроку(к);
          если к &lt; 10 тогда НомерПоля := "0" + НомерПоля;
          ИмяПоля := "STRFIELD" + НомерПоля;
          если Позиция(ИмяПоля, СтроковыеПоля) = 0 тогда
          начало
            результат := да;
            если СтроковыеПоляСлоев.ПараметрСуществует(Алиас) тогда
              СтроковыеПоляСлоев.Значение(Алиас) := СтроковыеПоляСлоев.Значение(Алиас) + "," + ИмяПоля
            иначе
              СтроковыеПоляСлоев.Значение(Алиас) := СтроковыеПоля + "," + ИмяПоля;
            прервать;
          конец;
        конец;  
  конец;

  // Комментарий
  функция ДобавитьПолеКодВСлой(Алиас: строка);
  переменные
    Данные: СтатическиеДанные;
  начало
    Данные := СоздатьСтатическиеДанные;
    Данные.СоединитьБД;
    Данные.Запрос := "[PumpData]{select l.ID LayerID, lf.DBName IsCode from Layers l left join LayerFields lf "#13#10
    + "on lf.RecordIndex = l.ID and (lf.DBName = 'CODE' or lf.FieldName = 'Код') where l.Alias in (@LayerAlias)}";
    Данные.Параметр("LayerAlias") := Алиас;
    Данные.Открыть;
    если Данные.Поле('IsCode').Пустое тогда
    начало
      ВыполнитьЗапрос("update LayerFields set DisplayLabel = 'ИД' where RecordIndex = :LayerID and DBName = 'ID'", МассивИз(Данные.Поле('LayerID').КакЦелое));
      ВыполнитьЗапрос("insert into LayerFields (RecordIndex, FieldName, DisplayLabel, DBName, FieldType, FieldRole, Mask)"#13#10
      + "values(:LayerID, 'Code', 'Код', 'CODE', 6, 2, '-')", МассивИз(Данные.Поле('LayerID').КакЦелое));
    конец;

  конец;

  функция ПараметрыОткрытия(Имена, Значения: Переменная): IVariables; будущая;

  // Комментарий
  функция СоздатьКонтроллер(Имя: строка): Переменная;
  переменные
    ПараметрыВызова: IVariables; 
  начало
    ПараметрыВызова := CreateVariables;
    ПараметрыВызова.Значение("ИмяОбъекта") := Имя;
    ПолучитьМенеджерСлоев.PerformController('Платформа.СоздатьОбъект', ПараметрыВызова);
    результат := ПараметрыВызова.Значение("Объект"); 
  конец;
  
  // Комментарий
  функция БезЗапятой(СЗапятой: строка): строка;
  начало
    если Подстрока(СЗапятой, Длина(СЗапятой), 1) = ',' тогда
      результат := Подстрока(СЗапятой, 1, Длина(СЗапятой) - 1)
    иначе
      результат := СЗапятой;
  конец;


  // Комментарий
  функция ЭкспортОписаний(СписокСлоев: строка);
  переменные
    Слой: ILayer;
    Параметры: IVariables;
  начало
    если СписокСлоев &lt;&gt; '' тогда
    начало
      СписокСлоев := БезЗапятой(СписокСлоев);

      Слой := ПолучитьМенеджерСлоев.CreateLayerByAlias("Платформа.Слои.ОписанияСлоев");
      Параметры := CreateVariables;

      Слой.SelectData(ПараметрыОткрытия(МассивИз('$Layer.ID', '$Layer.ID.Ограничение'), МассивИз(СписокСлоев, 'in')));
      //Параметры.Значение("СписокВыделенныхАтрибутов") := СписокСлоев; 
      Параметры.Значение("Слой") := Слой;
      Параметры.Значение("СброситьКэш") := да;   
      Параметры.Значение("СохранениеКомпонента") := СоздатьКонтроллер('Платформа.Синхронизация.ЭкспортИмпорт.ЭкспортДокументаВФайл');
      //Параметры.Значение("ТипЭкспорта") := 0;
      //Параметры.Значение("ЭкспортироватьВОдинФайл") := 1;
      ПолучитьМенеджерСлоев.PerformController('Платформа.Синхронизация.ЭкспортИмпорт.ВнешнееЧтениеКомпонентов', Параметры);
    конец;
  конец;


  // Комментарий
  функция СоздатьИдентификаторы: СтатическиеДанные;
  начало
    результат := СоздатьСтатическиеДанные;
    результат.ДобавитьЦелоеПоле('LayerID');
    результат.ДобавитьЦелоеПоле('NaturalKey');
    результат.ДобавитьСтроковоеПоле('LayerList', 4096);
    результат.Open;
  конец;


  // Комментарий
  функция СписокИдентификатов(Поля: СтатическиеДанные; ИмяПоля: строка): строка;
  переменные
    Идентификаторы: СтатическиеДанные;
  начало
    Идентификаторы := СоздатьСтатическиеДанные;
    Идентификаторы.ДобавитьЦелоеПоле(ИмяПоля);
    Идентификаторы.ДобавитьСтроковоеПоле('LayerList', 4096);
    Идентификаторы.Open;
    Идентификаторы.GroupData(Поля, 'keys=' + ИмяПоля + ';LayerList=' + ИмяПоля);
    ВнутренняяГруппировка(Идентификаторы,'keys=;LayerList=sum(LayerList+",")', да);
    результат := Идентификаторы.Поле('LayerList').КакСтрока;
  конец;

  // Комментарий
  функция СоздатьПоля: СтатическиеДанные;
  начало
    результат := СоздатьСтатическиеДанные;
    результат.ДобавитьЦелоеПоле('ID');
    результат.ДобавитьЦелоеПоле('LayerID');
    результат.ДобавитьЦелоеПоле('NaturalKey');
    результат.ДобавитьСтроковоеПоле('Alias',255);
    результат.ДобавитьСтроковоеПоле('fieldname',255);
    результат.ДобавитьСтроковоеПоле('DBName',255);
    результат.ДобавитьСтроковоеПоле('TableName',255);
    результат.ДобавитьСтроковоеПоле('Reason',4096);
  конец;
  
  // Комментарий
  функция ПараметрыОткрытия(Имена, Значения: Переменная): IVariables;
  переменные
    ж: целое;
  начало
    результат := CreateVariables;
    от ж := Имена.НижняяГраницаМассива(1) до Имена.ВерхняяГраницаМассива(1) делать
      результат.Значение(Имена.КакСтрока(ж)) := Значения.КакСтрока(ж);
  конец;
  
  // Сравнение имен полей
  функция ЗначениеПараметраПохоже(ДанныеПередачи: СтатическиеДанные; Имя, Значение: строка): целое;
  переменные
    сс: СтатическиеДанные;
  начало
    результат := нет;
    если ДанныеПередачи.Локализовать("ИмяПараметра", МассивИз(Имя), 0) тогда
    начало
      сс := СоздатьСтатическиеДанные;
      сс.ДобавитьСтроковоеПоле("СтрокаИсточника", 255);
      сс.Открыть;
      сс.СкопироватьЗапись(1, ДанныеПередачи);
      сс.Filter := "СтрокаИсточника like '%" + Значение + "%'";
      сс.Filtered := да;
//      сс.Группировать(nil, "ИмяПараметра=ИмяПараметра;СтрокаИсточника=СтрокаИсточника;Флаг=СтрокаИсточника like '%" + Значение + "%'");
      результат := не (сс.Bof и сс.Eof);
    конец;
  конец;
  
  // Сравнение имен полей
  функция ЗначениеПараметраВ(ДанныеПередачи: СтатическиеДанные; Имя, Значение: строка): целое;
  переменные
    сс: СтатическиеДанные;
  начало
    результат := нет;
    если ДанныеПередачи.Локализовать("ИмяПараметра", МассивИз(Имя), 0) тогда
    начало
      если Значение &lt;&gt; "" тогда
      начало
        сс := СоздатьСтатическиеДанные;
        сс.ДобавитьСтроковоеПоле("СтрокаИсточника", 255);
        сс.Открыть;
        сс.СкопироватьЗапись(1, ДанныеПередачи);
        сс.Filter := "СтрокаИсточника in [" + Значение + "]";
        сс.Filtered := да;
        результат := не (сс.Bof и сс.Eof);
      конец;
    конец;
  конец;
  
  // Сравнение для Маски
  функция ЗначениеПараметраРавно(ДанныеПередачи: СтатическиеДанные; Имя, Значение: строка): целое;
  переменные
    сс: СтатическиеДанные;
  начало
    результат := нет;
    если ДанныеПередачи.Локализовать("ИмяПараметра", МассивИз(Имя), 0) тогда
    начало
      сс := СоздатьСтатическиеДанные;
      сс.ДобавитьСтроковоеПоле("СтрокаИсточника", 255);
      сс.Открыть;
      сс.СкопироватьЗапись(1, ДанныеПередачи);

      сс.Filter := "/*$T-*/ СтрокаИсточника = '" + Значение + "' /*$T=*/";
      сс.Filtered := да;
      результат := не (сс.Bof и сс.Eof);
    конец;
  конец;
  
  // Комментарий
  функция ПолучитьПодключенияСправочников(ТекущиеПередачи: СтатическиеДанные; алиасКлассификатор: строка): строка;
  переменные
    ПоляСправочников: СтатическиеДанные;
  начало
    результат := '';
    ТекущиеПередачи.Filter := "ИмяПараметра = 'АлиасСлоя' and СтрокаИсточника = '" + алиасКлассификатор + "'";
    ПоляСправочников := СоздатьСтатическиеДанные;
    ПоляСправочников.ДобавитьЦелоеПоле('ИДПодключения');
    ПоляСправочников.Открыть;
    ПоляСправочников.Закачать(ТекущиеПередачи);
    ПоляСправочников.ВНачало; 
    пока не ПоляСправочников.ВКонце делать
    начало
      ТекущиеПередачи.Filter := "ИмяПараметра = 'Имя' and ИДПодключения = " + ЦелоеВСтроку(ПоляСправочников.Поле('ИДПодключения').КакЦелое);
      если результат = '' тогда
        результат := "'" + ТекущиеПередачи.Поле('СтрокаИсточника').КакСтрока + "'"
      иначе
        результат := результат + ",'" + ТекущиеПередачи.Поле('СтрокаИсточника').КакСтрока + "'";
      ПоляСправочников.Следующая;
    конец;
    ТекущиеПередачи.Filter := "";
  конец;

  // Комментарий
  функция ПолучитьПоляИзДескриптора(алиасКлассификатор, ПодстрокаРус, ПодстрокаЛат: строка): СтатическиеДанные;
  переменные
    Контроллеры, Обработчики, НужнаяПередача, Передача, Расширения: ILayer;
    ДанныеОбработчиков, ДанныеПередачи, ДанныеРасширений, ТекущиеПередачи: СтатическиеДанные;
    ПоляПодключений, Reason: строка;
  начало
    результат := СоздатьПоля;
    результат.Открыть;
    
    Контроллеры := МенеджерСлоев.CreateLayerByAlias(аКонтроллеры);
    Контроллеры.SelectData(ПараметрыОткрытия(МассивИз("$Layer.Наименование", "$Layer.Наименование.Ограничение"), МассивИз(КонтроллерыДобавленияПоля, "in")));
    
    Обработчики := МенеджерСлоев.CreateLayerByAlias(аОбработчики);
    Обработчики.SelectData(ПараметрыОткрытия(МассивИз("$Layer.ИДКонтроллера", "$Layer.ИДКонтроллера.Ограничение", "$Layer.ИмяТочкиПодключения"), 
    МассивИз(БезЗапятой(СписокИдентификатов(Контроллеры.LayerData, 'ИД')), "in", "ИнициализацияКомпонента")));
    
    Передача := МенеджерСлоев.CreateLayerByAlias(аПередача);
    Передача.SelectData(ПараметрыОткрытия(МассивИз("$Layer.ИДПодключения", "$Layer.ИДПодключения.Ограничение"), 
    МассивИз(БезЗапятой(СписокИдентификатов(Обработчики.LayerData, 'ИД')), "in")));
    
    Расширения := МенеджерСлоев.CreateLayerByAlias(аРасширения);
    Расширения.SelectData(ПараметрыОткрытия(МассивИз("$Layer.ИД", "$Layer.ИД.Ограничение"), 
    МассивИз(БезЗапятой(СписокИдентификатов(Обработчики.LayerData, 'ИДЗаголовка')), "in")));
    
       
    ТекущиеПередачи := СоздатьСтатическиеДанные;
    ТекущиеПередачи.AssignFields(Передача.LayerData);
    ТекущиеПередачи.Открыть;
    ТекущиеПередачи.Filter := "";
    ТекущиеПередачи.Filtered := да;
    
    ДанныеРасширений := Расширения.LayerData;
    ДанныеРасширений.ВНачало;
    пока не ДанныеРасширений.ВКонце делать
    начало
      ТекущиеПередачи.Clear;
      Обработчики := Расширения.GetDetail('ПодключениеОбработчиков');
      ДанныеОбработчиков := Обработчики.LayerData;
      
      ДанныеОбработчиков.ВНачало;
      пока не ДанныеОбработчиков.ВКонце делать
      начало
        НужнаяПередача := Обработчики.GetDetail("ПередачаПараметров");
        ТекущиеПередачи.Закачать(НужнаяПередача.LayerData, "");
        
        ДанныеОбработчиков.Следующая;
      конец;
      
      ДанныеОбработчиков.ВНачало;
      пока не ДанныеОбработчиков.ВКонце делать
      начало
        НужнаяПередача := Обработчики.GetDetail("ПередачаПараметров");
        Reason := '';
        ПоляПодключений := ПолучитьПодключенияСправочников(ТекущиеПередачи, алиасКлассификатор);
        ДанныеПередачи := НужнаяПередача.LayerData;
        если (ЗначениеПараметраПохоже(ДанныеПередачи, "Имя", ПодстрокаРус)
        или ЗначениеПараметраПохоже(ДанныеПередачи, "Имя", ПодстрокаЛат)
        или ЗначениеПараметраПохоже(ДанныеПередачи, "ИмяПоляБД", ПодстрокаРус) 
        или ЗначениеПараметраПохоже(ДанныеПередачи, "ИмяПоляБД", ПодстрокаЛат) 
        или ЗначениеПараметраПохоже(ДанныеПередачи, "Формула", алиасКлассификатор)
        или ЗначениеПараметраВ(ДанныеПередачи, "ГлавноеПоле", ПоляПодключений))
        и (ЗначениеПараметраВ(ДанныеПередачи, "РольПоля", "1, 2"))
        и ЗначениеПараметраРавно(ДанныеПередачи, "Вставить", "1") тогда
        начало
          результат.Вставить;
          
          если ЗначениеПараметраПохоже(ДанныеПередачи, "Имя", ПодстрокаРус)
          или ЗначениеПараметраПохоже(ДанныеПередачи, "Имя", ПодстрокаЛат) тогда
            Reason := Reason + 'Дескриптор Имя; ';
          если ЗначениеПараметраПохоже(ДанныеПередачи, "ИмяПоляБД", ПодстрокаРус) 
          или ЗначениеПараметраПохоже(ДанныеПередачи, "ИмяПоляБД", ПодстрокаЛат) тогда
            Reason := Reason + 'Дескриптор ИмяПоляБД; ';
          если ЗначениеПараметраПохоже(ДанныеПередачи, "Формула", алиасКлассификатор) тогда
            Reason := Reason + 'Descr Формула; ';
          если ЗначениеПараметраВ(ДанныеПередачи, "ГлавноеПоле", ПоляПодключений) тогда
            Reason := Reason + 'Дескриптор ГлавноеПоле; ';
            
          результат.Поле('ID').КакЦелое := - ДанныеОбработчиков.Поле('ИД').КакЦелое;
          ДанныеПередачи.Локализовать("ИмяПараметра", МассивИз('Имя'), 0); результат.Поле('fieldname').КакСтрока := ДанныеПередачи.Поле('СтрокаИсточника').КакСтрока;
          результат.Поле('LayerID').КакЦелое := МенеджерСлоев.CreateLayerByAlias(ДанныеРасширений.Поле('ИмяКомпонента').КакСтрока).LayerID;
          ДанныеПередачи.Локализовать("ИмяПараметра", МассивИз('ИмяПоляБД'), 0); результат.Поле('DBName').КакСтрока := ДанныеПередачи.Поле('СтрокаИсточника').КакСтрока;
          если ДанныеПередачи.Локализовать("ИмяПараметра", МассивИз('НатуральныйКлюч'), 0) тогда
            результат.Поле('NaturalKey').КакЦелое := СтрокаВЦелое(ДанныеПередачи.Поле('СтрокаИсточника').КакСтрока)
          /*иначе
            результат.Поле('NaturalKey').IsNull := да*/;
          
          результат.Поле('Alias').КакСтрока := ДанныеРасширений.Поле('ИмяКомпонента').КакСтрока;
          
          результат.Поле('Reason').КакСтрока := Reason;
          результат.Сохранить;
        конец;

        ДанныеОбработчиков.Следующая;
      конец;
      ДанныеРасширений.Следующая;
    конец;
  конец;

  // Комментарий
  функция ВыполнитьЗаменуВДескрипторе(НегативныйИД: целое; НоваяМаска: строка; ДлинаЗначения: целое; ИмяПоляБД: строка);
  переменные
    ИДПодключения: целое;
    Обработчики, Передача: ILayer;
    ДанныеПередачи: СтатическиеДанные;
  начало
    ИДПодключения := - НегативныйИД;
    Обработчики := МенеджерСлоев.CreateLayerByAlias(аОбработчики);
    Обработчики.SelectData(ПараметрыОткрытия(МассивИз("$Layer.ИД"), 
    МассивИз(ИДПодключения)));
    Передача := Обработчики.GetDetail("ПередачаПараметров");
    ДанныеПередачи := Передача.LayerData;
    если ДанныеПередачи.Локализовать("ИмяПараметра", МассивИз("Маска"), 0) тогда
    начало
      ДанныеПередачи.Edit;
      ДанныеПередачи.Поле("СтрокаИсточника").КакСтрока := НоваяМаска;
      ДанныеПередачи.Post;
    конец;
    если ДанныеПередачи.Локализовать("ИмяПараметра", МассивИз("ЗначениеПоУмолчанию"), 0) тогда
    начало
      ДанныеПередачи.Edit;
      ДанныеПередачи.Поле("СтрокаИсточника").КакСтрока := ЛевоеВыравнивание(ДанныеПередачи.Поле("СтрокаИсточника").КакСтрока, ДлинаЗначения, "0");
      ДанныеПередачи.Post;
    конец;           
    если ДанныеПередачи.Локализовать("ИмяПараметра", МассивИз("ТипПоля"), 0) тогда
    начало
      ДанныеПередачи.Edit;
      ДанныеПередачи.Поле("СтрокаИсточника").КакСтрока := "21";
      ДанныеПередачи.Post;
    конец;
    если ДанныеПередачи.Локализовать("ИмяПараметра", МассивИз("ИмяПоляБД"), 0) тогда
    начало
      если ИмяПоляБД &lt;&gt; "" тогда
      начало
        ДанныеПередачи.Edit;
        ДанныеПередачи.Поле("СтрокаИсточника").КакСтрока := ИмяПоляБД;
        ДанныеПередачи.Post;
      конец;
    конец;
    Передача.Commit;
  конец;

  
  // Комментарий
  функция ПреобразоватьСлои(ТекстВФайл: строка; ОбновленияНатуральныхКлючей: СтатическиеДанные; СписокСлоев: строка; Лог: ОкноВывода; НоваяМаска, алиасКлассификатор, ПодстрокаРус, ПодстрокаЛат: строка; ДополнительныйСлой: строка; ДлинаЗначения: целое);
  переменные
    ссПоляСлоя: СтатическиеДанные;
    КоличествоИзменений: целое;
    Запрос, стр, Addent: строка;
    ИмяПоляБД, УсловиеПоля: строка;
    ИДПоля, LayerID, DBName, Alias, FieldName, Reason, NaturalKey, TableName: Поле;
    ЗанятыеПоля: ILayer;
    ЗанятыеПоляДанные: СтатическиеДанные;
  начало
    Лог.Вывести('= Преобразуем ' + алиасКлассификатор + ' в буквенно-цифровой =');
    
    ДобавитьПолеКодВСлой(ДополнительныйСлой);
    
    ЗанятыеПоля := ПолучитьМенеджерСлоев.CreateLayerByAlias(аЗанятыеПоля);
    ЗанятыеПоляДанные := ЗанятыеПоля.LayerData;
    ЗанятыеПоля.Open;

    
    ссПоляСлоя := СоздатьПоля;

    Запрос := "[PumpData]"#13#10;

    //Addent := "((" + ЕслиЗначение(IsOracle(), "and lf.Mask is not null", "and lf.Mask &lt;&gt; '' and lf.Mask is not null") + " and lf.Mask = '" + НоваяМаска + "') or lf.FieldType = 21)";
    Addent := " and lf.FieldRole in (1, 2)";
//    + " and l.Alias like 'облОмск%'";
//    + "and (l.Alias like 'КонсБюджет%'
//or l.Alias like 'НСИ%'
//or l.Alias like 'Отчетность%'
//or l.Alias like 'ПаспортГУ%'
//or l.Alias like 'Планирование%'
//or l.Alias like 'ПланированиеБА%'
//or l.Alias like 'Платформа%'
//or l.Alias like 'Платформа.УРМ%'
//or l.Alias like 'РасчетЗатрат%'
//or l.Alias like 'РасчетЗатратПБС%'
//or l.Alias like 'РеестрГосУслуг%'
//or l.Alias like 'РеестрПоправок%'
//or l.Alias like 'РеестрПоправок.ВЦП%'
//or l.Alias like 'РРО%'
//or l.Alias like 'ЦелиПоказатели%') and lf.FieldRole &lt; 3";
    
    Запрос := Запрос 
    + "{select l.Alias Alias, lf.ID ID, lf.FieldName FieldName, lf.DBName DBName, l.ID LayerID, 'Запись слоя' Reason, lf.NaturalKey NaturalKey, l.TableName TableName"#13#10
    + "from Layers l join LayerFields lf on l.ID = lf.RecordIndex  "#13#10
    + "left join LayerFields lfcls on lf.LinkedField = lfcls.ID  "#13#10
    + "where lfcls.ClsName = '" + алиасКлассификатор + "'"#13#10
    + Addent + "}"#13#10
    + "{select l.Alias Alias, lf.ID ID, lf.FieldName FieldName, lf.DBName DBName, l.ID LayerID, 'DBName' Reason, lf.NaturalKey NaturalKey, l.TableName TableName"#13#10
    + "from Layers l join LayerFields lf on l.ID = lf.RecordIndex  "#13#10
    + "where (lf.DBName like '%" + ПодстрокаРус + "%' or lf.DBName like '%" + ПодстрокаЛат + "%') "#13#10
    + Addent + "}"#13#10
    + "{select l.Alias Alias, lf.ID ID, lf.FieldName FieldName, lf.DBName DBName, l.ID LayerID, 'FieldName/DisplayLabel' Reason, lf.NaturalKey NaturalKey, l.TableName TableName"#13#10
    + "from Layers l join LayerFields lf on l.ID = lf.RecordIndex"#13#10
    + "where (lf.FieldName like '%" + ПодстрокаРус + "%' or lf.FieldName like '%" + ПодстрокаЛат + "%' or lf.DisplayLabel like '%" + ПодстрокаРус + "%' or lf.DisplayLabel like '%" + ПодстрокаЛат + "%')"#13#10
    + Addent + "}"#13#10
    + "{select l.Alias Alias, lf.ID ID, lf.FieldName FieldName, lf.DBName DBName, l.ID LayerID, 'Formula' Reason, lf.NaturalKey NaturalKey, l.TableName TableName"#13#10
    + "from Layers l join LayerFields lf on l.ID = lf.RecordIndex"#13#10
    + "where lf.Formula1 like '%Классификаторы." + ПодстрокаРус + "%'"#13#10
    + Addent + "}"#13#10
    + "{select l.Alias Alias, lf.ID ID, lf.FieldName FieldName, lf.DBName DBName, l.ID LayerID, '" + алиасКлассификатор + "' Reason, lf.NaturalKey NaturalKey, l.TableName TableName"#13#10
    + "from Layers l join LayerFields lf on l.ID = lf.RecordIndex"#13#10
    + "where l.Alias = '" + алиасКлассификатор + "' and lf.FieldName = 'Код'"#13#10
    + Addent + "}"#13#10
    + "{select l.Alias Alias, lf.ID ID, lf.FieldName FieldName, 'Не переносить' DBName, l.ID LayerID, 'АСБюджет.ВнешниеТаблицы." + алиасКлассификатор + "' Reason, lf.NaturalKey NaturalKey, l.TableName TableName"#13#10
    + "from Layers l join LayerFields lf on l.ID = lf.RecordIndex"#13#10
    + "where l.Alias in (" + ДополнительныйСлой + ") and lf.DisplayLabel = 'Код'"#13#10
    + Addent + "}"#13#10;
    /* 
      Запись слоя - поля у которых главное поле с указанным классификатором
      DBName - в имени поля БД входит ПодстрокаРус или ПодстрокаЛат
      FieldName/DisplayLabel - то же что и для DBName, только для указанных полей
      Formula - ссылка в поле формула на классификатор
      Все эти поля должны иметь необработанную маску (старую маску)
    */

    ссПоляСлоя.СоединитьБД;
    ссПоляСлоя.Запрос := Запрос;
    ссПоляСлоя.Open;
    ссПоляСлоя.Закачать(ПолучитьПоляИзДескриптора(алиасКлассификатор, ПодстрокаРус, ПодстрокаЛат), "");
    //Устраняем дублирование в ссПоляСлоя
    ВнутренняяГруппировка(ссПоляСлоя,'keys=ID;Reason=sum(Reason+"; ")', да);
    ссПоляСлоя.IndexFieldNames:='Alias;FieldName';
//    показать(ссПоляСлоя); 
//    выход;
    СписокСлоев := ''; //СписокСлоев + СписокИдентификатов(ссПоляСлоя);
    ОбновленияНатуральныхКлючей.Группировать(ссПоляСлоя, 'insert=true;update=true;keys=LayerID;LayerID=LayerID;LayerList=Alias;NaturalKey=sum(NaturalKey)');
    

    /* Update поля из ссПоляСлоя */
    ТекстВФайл := ТекстВФайл + '&lt;p&gt;Классификатор ' + ПодстрокаРус + ' преобразован в буквенно-цифровой.&lt;/p&gt;';
    КоличествоИзменений:=0;
    если ссПоляСлоя.ЧислоЗаписей&gt;0 тогда
    начало
      ИДПоля := ссПоляСлоя.ПолеПоИмени('ID');
      DBName := ссПоляСлоя.ПолеПоИмени('DBName');
      Alias := ссПоляСлоя.ПолеПоИмени('Alias');
      FieldName := ссПоляСлоя.ПолеПоИмени('FieldName');
      Reason := ссПоляСлоя.ПолеПоИмени('Reason');
      LayerID := ссПоляСлоя.ПолеПоИмени('LayerID');
      NaturalKey := ссПоляСлоя.ПолеПоИмени('NaturalKey');
      TableName := ссПоляСлоя.ПолеПоИмени('TableName');   
      
      ТекстВФайл:=ТекстВФайл+'&lt;TABLE border="1" style="border-collapse:collapse; border: 1px solid;"&gt;';
      ТекстВФайл:=ТекстВФайл+'&lt;TR&gt;&lt;TH&gt;Слой&lt;/TH&gt;&lt;TH&gt;Поле&lt;/TH&gt;&lt;TH&gt;Причина изменения&lt;/TH&gt;&lt;TH&gt;Входит в натуральный ключ&lt;/TH&gt;&lt;TH&gt;Перенос&lt;/TH&gt;&lt;/TR&gt; ';
      ссПоляСлоя.ВНачало;
      пока не ссПоляСлоя.ВКонце делать
      начало
        УсловиеПоля := "";
        если TableName.КакСтрока = 'LayerData' и СуществуетПоле(DBName.КакСтрока) тогда
        начало
          ЗанятыеПоляДанные.Insert;
          ЗанятыеПоляДанные.Поле('ИД').КакСтрока := ИДПоля.КакСтрока;
          ЗанятыеПоляДанные.Поле('АлиасСлоя').КакСтрока := Alias.КакСтрока;
          ЗанятыеПоляДанные.Поле('ИмяПоля').КакСтрока := FieldName.КакСтрока;
          ЗанятыеПоляДанные.Поле('ИмяПоляБД').КакСтрока := DBName.КакСтрока;
          ЗанятыеПоляДанные.Post;
        конец;
          
        
//          если СуществуетСвободноеСтроковоеПоле(СтроковыеПоля, Alias.КакСтрока, ИмяПоляБД) тогда
//            УсловиеПоля := ", DBName = '" + ИмяПоляБД + "', DefaultValue = LPAD(DefaultValue, " + ЦелоеВСтроку(ДлинаЗначения) + ", '0')";
            
//        
//        если ИДПоля.КакЦелое &lt; 0 тогда
//          ВыполнитьЗаменуВДескрипторе(ИДПоля.КакЦелое, НоваяМаска, ДлинаЗначения, ИмяПоляБД)
//        иначе
//          ВыполнитьЗапрос(Формат("update LayerFields set Mask = '%s', FieldType = 22" + УсловиеПоля + " where (ID = %d) " 
//          + ЕслиЗначение(IsOracle(), "and Mask is not null", "and Mask &lt;&gt; '' and Mask is not null") + " and Mask = '%s'", НоваяМаска, ИДПоля.КакЦелое, НоваяМаска));
        
        стр := 'Запомнили запись с ИД: ' + ЦелоеВСтроку(ИДПоля.КакЦелое) + '. Слой: ' + Alias.КакСтрока
        + ЕслиЗначение(NaturalKey.Пустое, '', ' |  Натуральный ключ надо обновлять ' + NaturalKey.AsString);
        //+ ЕслиЗначение(УсловиеПоля &lt;&gt; "", " | Сделан перенос данных из " + DBName.КакСтрока + " в " + ИмяПоляБД, ' | Не сделан перенос имя "' + DBName.КакСтрока + '" не является полем БД Планирования.')
        Лог.Вывести(стр);
        
        
        // сделаем перенос данных
        если УсловиеПоля &lt;&gt; "" тогда
        начало
          Запрос := Формат("update LayerData set %s = LPAD(%s, %d, '0') where (LayerRef = %d)", 
          ИмяПоляБД, DBName.КакСтрока, ДлинаЗначения, LayerID.КакЦелое);
          ВыполнитьЗапрос(Запрос);
//          если не NaturalKey.Пустое тогда
//          начало
//            Запрос := Формат("update LayerData set NaturalKey = Replace(NaturalKey, cast(%s as varchar%s(255)), %s) where (LayerRef = %d)", 
//            DBName.КакСтрока, ЕслиЗначение(IsOracle(), '2', ''), ИмяПоляБД, LayerID.КакЦелое);
//            ВыполнитьЗапрос(Запрос);
//          конец;
        конец;

        ТекстВФайл:=ТекстВФайл+'&lt;TR style="text-align:left; font-size: 12pt;"&gt;&lt;TH&gt;' + Alias.КакСтрока + '&lt;/TH&gt;&lt;TH&gt;' + FieldName.КакСтрока + '&lt;/TH&gt;&lt;TH&gt;' 
        + Reason.КакСтрока + '&lt;/TH&gt;&lt;TH&gt;' + NaturalKey.AsString + '&lt;/TH&gt;&lt;TH&gt;' 
        + ЕслиЗначение(УсловиеПоля &lt;&gt; "", "Сделан перенос данных из " + DBName.КакСтрока + " в " + ИмяПоляБД, 'Не сделан перенос имя "' + DBName.КакСтрока + '" не является полем БД Планирования.') + '&lt;/TH&gt;&lt;/TR&gt; ';
        КоличествоИзменений:=КоличествоИзменений + 1; 
        ссПоляСлоя.Следующий;
      конец;
      Лог.Вывести('= Преобразование завершено!!! =');  
      Лог.Вывести('Количество измененных записей: ' + ЦелоеВСтроку(КоличествоИзменений));
      ТекстВФайл:=ТекстВФайл+'&lt;/TABLE&gt;';
    конец  
    иначе
    начало
      стр := 'У всех полей связанных с "' + алиасКлассификатор + '" установлена маска "' + НоваяМаска + '". Обновлять базу не требуется.';
      ТекстВФайл := ТекстВФайл+'&lt;P&gt;' + стр + '&lt;/P&gt;';
      Лог.Вывести(стр);
    конец;
    ТекстВФайл:=ТекстВФайл+'Количество измененных записей: ' + ЦелоеВСтроку(КоличествоИзменений);
    ТекстВФайл:=ТекстВФайл+'&lt;p&gt;Указанные причины изменения:&lt;/p&gt;';   
    ТекстВФайл:=ТекстВФайл+'&lt;p&gt;1. Запись слоя&lt;/p&gt;'; 
    ТекстВФайл:=ТекстВФайл+'&lt;p&gt;2. DBName (в поле DBName найдены значения: ' + ПодстрокаРус + ' или ' + ПодстрокаЛат + ') или ИмяПоляБД в дескрипторе&lt;/p&gt;'; 
    ТекстВФайл:=ТекстВФайл+'&lt;p&gt;3. Formula (в поле Formula найдены значения: Классификаторы.' + ПодстрокаРус + ') или Формула в дескрипторе&lt;/p&gt;'; 
    ТекстВФайл:=ТекстВФайл+'&lt;p&gt;4. CLSName (в поле "Имя классификатора" ("CLSName") найдены значения: ' + ПодстрокаЛат + ' или Классификаторы.' + ПодстрокаРус + ') или АлиасСлоя в дескрипторе&lt;/p&gt;'; 
    ТекстВФайл:=ТекстВФайл+'&lt;p&gt;5. FieldName/DisplayName (в полях FieldName и DisplayName встречаются ' + ПодстрокаРус + ' или ' + ПодстрокаЛат + ') или Имя в дескрипторе&lt;/p&gt;';
    
    ЗанятыеПоля.Commit;   
  конец;  

переменные
  Лог: ОкноВывода;
  ТекстВФайл, Шапка: строка;
  ДлинаТекста: целое;
  Файл: целое;
  СтроковыеПоля: IVariables;
  СписокСлоев: строка;
  ОбновленияНатуральныхКлючей: СтатическиеДанные;
//  Идентификаторы: СтатическиеДанные;
начало
  Лог := ОкноВывода;
  Лог.Очистить;
  если СформироватьАлиасБД("Planning", ПараметрыПодключения) тогда
  начало
    МенеджерСлоев := ПолучитьМенеджерСлоев;
   
    Шапка:='&lt;html&gt;&lt;head&gt;&lt;title&gt;Преобразовали Классификаторы к буквенно-цифровой маске&lt;/title&gt;
                &lt;style type="text/css"&gt;
                   td { 
                    font-size: 10pt;
                    font-weight: normal;
                   }
                   th { 
                    font-size: 10pt;
                    font-weight: normal; 
                   }
                  &lt;/style&gt;
                &lt;/head&gt;&lt;body&gt;';

    СтроковыеПоля := СоздатьКоллекцию;
  //  Идентификаторы := СоздатьИдентификаторы;
    СписокСлоев := '';
    ОбновленияНатуральныхКлючей := СоздатьИдентификаторы;                    
    ПреобразоватьСлои(ТекстВФайл, ОбновленияНатуральныхКлючей, СписокСлоев, Лог, "&gt;aa.a.aaaa", "Классификаторы.ЦСР", "ЦСР", "CSR", "'АСБюджет.ВнешниеТаблицы.Классификаторы.КЦСР'", 7);
  //  ПреобразоватьСлои(ТекстВФайл, СтроковыеПоля, Лог, "&gt;aaa.aa.aaaa", "Классификаторы.КодСубсидии", "Субс", "Subsid", "'АСБюджет.ВнешниеТаблицы.Классификаторы.КодСубсидии','АСБюджет.Экспорт.Классификаторы.КодСубсидий'", 9);
//    ПреобразоватьСлои(ТекстВФайл, ОбновленияНатуральныхКлючей, СтроковыеПоля, СписокСлоев, Лог, "&gt;a.aa.aaa.aaa", "Классификаторы.ЦелевыхСредств", "Целев%сред", "Transfert", "'АСБюджет.ВнешниеТаблицы.Классификаторы.КодЦелевыхСредств'", 9);
//    выход;
//    ЭкспортОписаний(СписокСлоев);
    
    ОбновленияНатуральныхКлючей.Filter := 'NaturalKey&gt;0';
    ОбновленияНатуральныхКлючей.Filtered := да;
    ВнутренняяГруппировка(ОбновленияНатуральныхКлючей, 'keys=;LayerList=sum(LayerList + #13#10)', да);
    Лог.Вывести(#13#10#13#10'Слои требующие обновления натуральных ключей:');
    Лог.Вывести(ОбновленияНатуральныхКлючей.Поле('LayerList').КакСтрока);
    
    ТекстВФайл:=Шапка+'&lt;p&gt;Слои требующие обновления натуральных ключей:&lt;/p&gt;';
    //ТекстВФайл:=ТекстВФайл+'&lt;p&gt;' + ЗаменитьПодстроку(ОбновленияНатуральныхКлючей.Поле('LayerList').КакСтрока, #13#10, '&lt;br&gt;', да) + '&lt;/p&gt;';
    ТекстВФайл:=ТекстВФайл+'&lt;pre&gt;' + ОбновленияНатуральныхКлючей.Поле('LayerList').КакСтрока + '&lt;/pre&gt;';
  конец
  иначе
    Лог.Вывести('Ошибка при подключении к базе Planning '#13#10 + ПараметрыПодключения);
  
  Лог.Показать; 
  
  ТекстВФайл:=ТекстВФайл+'&lt;/body&gt;&lt;/html&gt;';
  ДлинаТекста:=Длина(ТекстВФайл);
  попытка
    Файл := FileCreate('НатКлючи_Для_Обновления.html');
    FileWrite(Файл,ТекстВФайл,ДлинаТекста);
  обязательно
    FileClose(Файл);  
  конец;  
конец.
</script>
</registry>