пятница, 10 августа 2012 г.

Сохранение запроса в файл консоли отчетов/запросов

       Идея написания данной фичи была давно, но никак не доходили руки. Вдохновением для реализации была небольшая доработка консоли запросов http://infostart.ru/public/143349/.
      
       Данный функционал сохраняет запрос с параметрами в файл с деревом значений, который открывается консолью отчетов и консолью запросов. Имеются четыре основных режима работы функции сохранения - на рабочий стол, в документы, в указанный каталог/файл и используя диалог выбора файла. Также можно сохранить значение каталога файлов запросов и указывать только имя создаваемого файла. Режимы сохранение являются наброской, "допилить" "под себя" займет немного времени.
Функция ЗапросВФайл(Запрос, ВариантСохранения = Неопределено, ИмяЗапроса="") Экспорт
    Перем ИмяКаталога;
    Перем ИмяФайла;

    // Получение имен каталога и файла
    Если ВариантСохранения = 0 Тогда
        ДиалогВыбораФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);

        ДиалогВыбораФайла.Заголовок = "Укажите файл для сохранения запроса";
        ДиалогВыбораФайла.Фильтр = "Файлы запросов (*.sel)|*.sel|Файлы отчетов (*.rcf)|*.rcf|Все файлы (*.*)|*.*";
        ДиалогВыбораФайла.Расширение = "sel";

        Если ДиалогВыбораФайла.Выбрать() Тогда
            ПолучитьКаталогИИмяФайла(ДиалогВыбораФайла.ПолноеИмяФайла, ИмяКаталога, ИмяФайла);;
        КонецЕсли;
    ИначеЕсли ВариантСохранения = 1 Тогда
        WSS=Новый COMОбъект("WScript.Shell");
        ИмяКаталога = Строка(WSS.SpecialFolders().Item("Desktop"));
    ИначеЕсли ВариантСохранения = 2 Тогда
        WSS=Новый COMОбъект("WScript.Shell");
        ИмяКаталога = Строка(WSS.SpecialFolders().Item("MyDocuments"));
    ИначеЕсли ТипЗнч(ВариантСохранения) = Тип("Строка") Тогда
        ПолучитьКаталогИИмяФайла(ВариантСохранения, ИмяКаталога, ИмяФайла);
    Иначе
        Возврат Ложь;
    КонецЕсли;

    Если Не ЗначениеЗаполнено(ИмяКаталога) Тогда
        КаталогСохраненияФайлов = ВосстановитьЗначение("КаталогСохраненияФайлов");
        Если КаталогСохраненияФайлов = Неопределено Тогда
            WSS=Новый COMОбъект("WScript.Shell");
            ИмяКаталога = Строка(WSS.SpecialFolders().Item("Desktop")) + "\";
        Иначе
            ИмяКаталога = КаталогСохраненияФайлов;
        КонецЕсли;
    КонецЕсли;

    Если Не ЗначениеЗаполнено(ИмяФайла) Тогда
        ИмяФайла = "Запрос.sel"
    ИначеЕсли Найти(ИмяФайла, ".") = 0 Тогда
        ИмяФайла = ИмяФайла + ".sel";
    КонецЕсли;

    // {{ Если файл сущетвует
    //      - это файл запросов - добавление строки в дерево запосов
    //      - если это не файл запросов - перезаписывание файла
    Файл = Новый Файл(ИмяКаталога + "\" + ИмяФайла);
    ЗначениеФайла = Неопределено;
    Если файл.Существует() Тогда
        ЗначениеФайла = ЗначениеИзФайла(ИмяКаталога + "\" + ИмяФайла)
    КонецЕсли;

    // {{ Создание структурированого дерева значений
    Если ТипЗнч(ЗначениеФайла) = Тип("ДеревоЗначений") Тогда
        ДеревоЗапросов = ЗначениеФайла;
    Иначе
        ДеревоЗапросов = Новый ДеревоЗначений;
        ДеревоЗапросов.Колонки.Добавить("Запрос");
        ДеревоЗапросов.Колонки.Добавить("ТекстЗапроса");
        ДеревоЗапросов.Колонки.Добавить("ПараметрыЗапроса");
        //ДеревоЗапросов.Колонки.Добавить("СпособВыгрузки");
        ДеревоЗапросов.Колонки.Добавить("ТипОформления");
    КонецЕсли;

    // Инициализация параметор запроса
    ПараметрыЗапроса = Новый ТаблицаЗначений;
    ПараметрыЗапроса.Колонки.Добавить("ИмяПараметра");
    ПараметрыЗапроса.Колонки.Добавить("ЭтоВыражение");
    ПараметрыЗапроса.Колонки.Добавить("ЗначениеПараметра");

    Для Каждого Параметр Из Запрос.Параметры Цикл
        ПараметрЗапроса = ПараметрыЗапроса.Добавить();
        ПараметрЗапроса.ИмяПараметра = Параметр.Ключ;
        ПараметрЗапроса.ЭтоВыражение = Ложь;
        Если ТипЗнч(Параметр.Значение) = Тип("Массив") Тогда
            СписокЗначения = Новый СписокЗначений;
            СписокЗначения.ЗагрузитьЗначения(Параметр.Значение);
            ПараметрЗапроса.ЗначениеПараметра = СписокЗначения;
        Иначе
            ПараметрЗапроса.ЗначениеПараметра = Параметр.Значение;
        КонецЕсли;
    КонецЦикла;

    // Добавление запроса в дерево запросов
    ИмяЗапроса = ?(ЗначениеЗаполнено(ИмяЗапроса), ИмяЗапроса, "Запрос");
    ИтоговоеИмяЗапроса = ИмяЗапроса; Итерация = 1;
    Пока Не ДеревоЗапросов.Строки.Найти(ИтоговоеИмяЗапроса) = Неопределено Цикл
        ИтоговоеИмяЗапроса = ИмяЗапроса + Строка(Итерация);
        Итерация = Итерация + 1;
    КонецЦикла;

    // Добавление текущего запроса
    СтрокаЗапрос = ДеревоЗапросов.Строки.Добавить();
    СтрокаЗапрос.Запрос = ИтоговоеИмяЗапроса;
    СтрокаЗапрос.ПараметрыЗапроса = ПараметрыЗапроса;
    СтрокаЗапрос.ТекстЗапроса = Запрос.Текст;
    //СтрокаЗапрос.СпособВыгрузки = ?(Найти(Запрос.Текст, "ИТОГИ")>0, 2, 1);
    СтрокаЗапрос.ТипОформления = СтандартноеОформление.Классика;

    // Сохранение файла
    Возврат ЗначениеВФайл(ИмяКаталога + "\" + ИмяФайла, ДеревоЗапросов)

КонецФункции

Процедура ПолучитьКаталогИИмяФайла(Знач ПолноеИмяФайла, ИмяКаталога, ИмяФайла) Экспорт

    // находим последний с конца "\" все что до него - это путь, после - имя
    НомерПозиции = СтрДлина(ПолноеИмяФайла);
    Пока НомерПозиции <> 0 Цикл
        Если Сред(ПолноеИмяФайла, НомерПозиции, 1) = "\" Тогда
            ИмяКаталога = Сред(ПолноеИмяФайла, 1, НомерПозиции - 1);
            ИмяФайла = Сред(ПолноеИмяФайла, НомерПозиции + 1);
            Возврат;
        КонецЕсли;
        НомерПозиции = НомерПозиции - 1;
    КонецЦикла;

    // так и не нашли слешей, значит все- это имя файла
    ИмяФайла = ПолноеИмяФайла;
    ИмяКаталога = "";

КонецПроцедуры 
P.S. После сохранения не забывайте удалять строку в табло отладки :)