Работа с Оpen Office из 1С на примере Calc

Формирование прайса

перем ooScript,Массив,диспетчер,OpenDoc,ServiceManager;
перем ооДата,ооЧисло,ооСтрока;
перем ooBold;
 
Функция ФильтрПоТаблицам()
  ОбработкаПрерыванияПользователя();
    Запрос=Новый Запрос();
    ТекстЗапроса =     
    "ВЫБРАТЬ
    |    СправочникНоменклатура.Ссылка КАК Номенклатура,
    |    МАКСИМУМ(ЦеныНоменклатурыСрезПоследних.Цена) КАК Цена,
    |    МАКСИМУМ(ЦеныНоменклатурыСрезПоследних.Цена) КАК ЛучшаяЦена,
    |    СУММА(ВложенныйЗапрос.КоличествоОстаток) КАК Остаток,
    |   СправочникНоменклатура.Наименование КАК Текст,
    |   """" КАК ПолныйКод
    |ИЗ
    |    Справочник.Номенклатура КАК СправочникНоменклатура
    |    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних КАК ЦеныНоменклатурыСрезПоследних
    |        ПО СправочникНоменклатура.Ссылка = ЦеныНоменклатурыСрезПоследних.Номенклатура
    |    ЛЕВОЕ СОЕДИНЕНИЕ  (ВЫБРАТЬ
        |            СУММА(ТоварыНаСкладахОстатки.КоличествоОстаток) КАК КоличествоОстаток,
    |            ТоварыНаСкладахОстатки.Номенклатура.Ссылка КАК НоменклатураСсылка,
    |            ТоварыНаСкладахОстатки.Склад.Ссылка КАК СкладСсылка
    |        ИЗ
    |            РегистрНакопления.ТоварыНаСкладах.Остатки КАК ТоварыНаСкладахОстатки
    |        ГДЕ
    |            ТоварыНаСкладахОстатки.Склад = &Склад
    |        СГРУППИРОВАТЬ ПО
    |            ТоварыНаСкладахОстатки.Номенклатура.Ссылка,
    |            ТоварыНаСкладахОстатки.Склад.Ссылка) КАК ВложенныйЗапрос
    |        ПО Номенклатура.Ссылка = ВложенныйЗапрос.НоменклатураСсылка
     |ГДЕ
    |    ЦеныНоменклатурыСрезПоследних.ТипЦен = &ТипЦен";
    Если Товары.Количество()>0 Тогда
        ТекстЗапроса = ТекстЗапроса + "
        |    И СправочникНоменклатура.Ссылка В ИЕРАРХИИ (&Товары)";
    КонецЕсли;
    Если Исключения.Количество()>0 Тогда
        ТекстЗапроса = ТекстЗапроса + "
        |    И (НЕ СправочникНоменклатура.Ссылка  В ИЕРАРХИИ(&Исключения))";
    КонецЕсли;
    ТекстЗапроса = ТекстЗапроса + "    
    |
    |СГРУППИРОВАТЬ ПО
    |    СправочникНоменклатура.Ссылка";
    Если Остаток <> 0 Тогда 
    ТекстЗапроса = ТекстЗапроса + "            
        |ИМЕЮЩИЕ
        |    СУММА(ВложенныйЗапрос.КоличествоОстаток) >= &Остаток";
    КонецЕсли;    
 
    ТекстЗапроса = ТекстЗапроса + "    
    |
    |    ИТОГИ
    |    СУММА(Цена),
    |    СУММА(ЛучшаяЦена),
    |    СУММА(Остаток)
    |ПО
    |    Номенклатура ИЕРАРХИЯ";
 
    Запрос.Текст = ТекстЗапроса;
    Запрос.УстановитьПараметр("Товары",Товары);
    Запрос.УстановитьПараметр("Исключения",Исключения);
    Запрос.УстановитьПараметр("Склад",Склад);
    Запрос.УстановитьПараметр("ТипЦен",ТипЦен);
    Запрос.УстановитьПараметр("Остаток", Остаток);
 
    ТаблицаТоваров = Запрос.Выполнить().Выгрузить();
    Возврат ТаблицаТоваров;
КонецФункции
 
 
 
 
процедура ВывестиВЯчейку(лист,строка,колонка,значение,тип )
    если тип = ооЧисло тогда
        лист.getCellByPosition(колонка,строка).SetValue(значение);
    иначеесли тип = ооСтрока тогда
        лист.getCellByPosition(колонка,строка).SetString(значение);
    иначеесли тип = ооДата тогда
        лист.getCellByPosition(колонка,строка).SetString(строка(значение));
    иначе
        сообщить("Неизвестный параметр тип = "+тип);
    конецЕсли;
КонецПроцедуры
 
процедура  ИзменитьШрифт (лист,колонка,строка,флаги)
перем _ooBold;
    _ooBold = 150;
если флаги % 2 = 1 тогда
    лист.getCellByPosition(колонка,строка).CharWeight = ooBold;
иначе
    сообщить("Неизвестный флаг = "+флаги);
конецЕсли;
 
 
КонецПроцедуры
 
процедура ИзменитьЦвет(sheet, колонка, строка,R,G,B)    
    sheet.getCellByPosition(колонка,строка).cellBackColor = R*256*256+G*256+B;
КонецПроцедуры
 
 
Процедура ПечатьШапки(sheet,ПечатаемАкцию=0,OpenDoc)
 
    ВывестиВЯчейку(sheet,1,1,строка("Прайс-лист"),ооСтрока);
    ВывестиВЯчейку(sheet,2,1,строка("ООО ""Парфюм-Карелия"""),ооСтрока);
    ВывестиВЯчейку(sheet,3,1,строка("Прайс лист сформирован на дату: " + строка(ТекущаяДата())),ооСтрока);
    sheet.getCellRangeByPosition(0,0,5,0).Merge(Истина);
    ВывестиВЯчейку(sheet,7,1,строка("№"),ооСтрока); 
     ВывестиВЯчейку(sheet,7,2,строка("Код"),ооСтрока);
    ВывестиВЯчейку(sheet,7,3,строка("Артикул"),ооСтрока);
    ВывестиВЯчейку(sheet,7,4,строка("Наименование"),ооСтрока);
    ВывестиВЯчейку(sheet,7,5,"Цена"+?(ЗначениеЗаполнено(Клиент)," / Лучшая",""),ооСтрока);
    Для х = 1 по КоличествоЗаявок цикл
        ВывестиВЯчейку(sheet,7,5 +  х,строка("Заявка"),ооСтрока);
    КонецЦикла;
конецПроцедуры
 
Процедура ПечатьТЗ(sheet,Таблица,OpenDoc)
    i=12; 
    Всего = Таблица.Количество();
    Для каждого Строка Из Таблица Цикл
        Если НЕ ЗначениеЗаполнено(Строка.Номенклатура) Тогда
            Продолжить;
        КонецЕсли;    
        ВывестиВЯчейку(sheet,i, 1,Число(Таблица.Индекс(Строка)+1),ооЧисло);
        ВывестиВЯчейку(sheet,i, 3,Строка(СокрЛП(Строка(Строка.Номенклатура.Артикул))),ооСтрока); 
        ВывестиВЯчейку(sheet,i, 4,Строка.Текст,ооСтрока);
 
 
        Если Строка.Номенклатура.ЭтоГруппа Тогда
            ИзменитьШрифт (sheet, 4, i,ooBold);
            ИзменитьЦвет(sheet, 4, i,220,220,220);
        Иначе                                   
            Если ЗначениеЗаполнено(Строка.Номенклатура) Тогда
                ВывестиВЯчейку(sheet,i, 2,Строка.Номенклатура.Код,ооСтрока); 
            КонецЕсли;
        КонецЕсли;
 
        ВывестиВЯчейку(sheet,i, 5,Строка.Цена,ооЧисло);
        i = i + 1;
    КонецЦикла;
    for j = 0 to 10 do
        sheet.Columns.GetByIndex(J).optimalWidth = 1;
        if j <> 4 then
            sheet.Columns.GetByIndex(J).HoriJustify = 3;
        endif;
    enddo
КонецПроцедуры
 
Процедура Сформировать()
    Если ЗначениеЗаполнено(Клиент) Тогда
        СписокДоговоров = СфорироватьСписокДоговоров();
    КонецЕсли;
    ТаблицаТоваров = ФильтрПоТаблицам();    
    Если ТаблицаТоваров.Количество() = 0 Тогда
        Предупреждение("Получен пустой список товаров!
            |Проверьте настройки фильтров.");
        Возврат;
    КонецЕсли;
 
    OpenDoc = НачатьВыводВOpenDocument();
       КудаВыводить = OpenDoc.getSheets().getByIndex(0);
    ПечатьШапки(КудаВыводить, 0, OpenDoc);     
    ПечатьТЗ(КудаВыводить,ТаблицаТоваров,OpenDoc); 
КонецПроцедуры
 
 
ооДата = 0;
ооЧисло = 1;
ооСтрока = 2;
 
ooBold = 1;

Чтение из прайса, формируем заказ покупателя

перем ТЗСтрок;
//////////ВСПОМОГАТЕЛЬНЫЕ И СЕРВИСНЫЕ ПРОЦЕДУРЫ ЗАГРУЗКИ////////////
Процедура ПрочитатьПрайс()
    // Вставить содержимое обработчика.
    перем массив;
 
    scr = новый COMОбъект("MSScriptControl.ScriptControl");
    scr.Language = "javascript";
    scr.AddCode("function SetItem(ind,val){Arr[ind]=val}");
    Массив = scr.Eval("Arr=new Array()");
 
 
    ServiceManager = новый COMОбъект("com.sun.star.ServiceManager");
    Desktop = ServiceManager.createInstance("com.sun.star.frame.Desktop");
    Document = Desktop.LoadComponentFromURL(convertToURL(ФайлПрайса), "_blank", 0, Массив);
    Sheets = Document.getSheets();
    Sheet = Sheets.getByName("Прайс_лист");
 
    ТЗСтрок.Очистить();
    i = 0;
    while Sheet.getCellByPosition(0,i).getString() <> "№" do
        i=i+1;
    enddo;
    НачалоНоменклатуры = i;
    i=0;
    while Sheet.getCellByPosition(i,НачалоНоменклатуры).getString() <> "Наименование" do
        i=i+1;
    enddo;
    НомерКолонкиТовар = i;
    i=0;
    while Sheet.getCellByPosition(i,НачалоНоменклатуры).getString() <> "Код" do
        i=i+1;
    enddo;
    НомерКолонкиКод = i;
    ДанныеФайла.Clear();
    i=5;
    while i<100 do   
        if Sheet.getCellByPosition(i,НачалоНоменклатуры).getString() = "" then
            прервать;
        конецесли;
 
        if Sheet.getCellByPosition(i,НачалоНоменклатуры).getString() <> "" then
            __ = ДанныеФайла.Добавить();
            __.Выбран = 1;
            __.КлиентИзФайла = Sheet.getCellByPosition(i,НачалоНоменклатуры).getString();
            __.КолонкаВФайле = i;
        endif;
        i=i+1;
    enddo;
 
    доКуда = i;
    ТЗ = новый ТаблицаЗначений;
    ТЗ.Колонки.Добавить("Код");
    ТЗ.Колонки.Добавить("Количество");
    Для каждого Строка Из ДанныеФайла Цикл
        ТЗ.Очистить();
        i = НачалоНоменклатуры;
        колонкаРасчета = Строка.КолонкаВФайле;
        while Sheet.getCellByPosition(НомерКолонкиТовар,i).getString() <> "" do   
            i=i+1;
            ОбработкаПрерыванияПользователя();
            if Sheet.getCellByPosition(колонкаРасчета,i).getString() = "" then
                продолжить;
            endif;
            __ = ТЗ.Добавить();
            __.Код = Sheet.getCellByPosition(НомерКолонкиКод,i).getString();
            __.Количество = Число(Sheet.getCellByPosition(колонкаРасчета,i).getString());
            состояние(""+__.Код+" / "+__.Количество);
 
        enddo;
        __ = ТЗСтрок.Добавить();
        __.КолонкаВФайле = колонкаРасчета;
        __.ТЗ =  ЗначениеВСтрокуВнутр(ТЗ);
    конецЦикла;
    ЭлементыФормы.ДанныеФайла.Видимость = Истина;
КонецПроцедуры
Процедура ИмяФайлаОбменаНачалоВыбора(Элемент, СтандартнаяОбработка)
    ДиалогВыбораФайла                                          =    Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
    ДиалогВыбораФайла.Фильтр                          =    "Файл данных (*.xls)|*.xls";
    ДиалогВыбораФайла.Расширение                        =    "xml";    
    ДиалогВыбораФайла.Заголовок                            =    "Выберите файл";
    ДиалогВыбораФайла.ПредварительныйПросмотр    =    Ложь;
    ДиалогВыбораФайла.ИндексФильтра                      =    0;
    Если ДиалогВыбораФайла.Выбрать() ТОгда
        ЭлементыФормы.Прочитать.Видимость = Истина;
        ЭлементыФормы.Склад.Видимость = Истина;
        ЭлементыФормы.Организация.Видимость = Истина;
        Элемент.Значение=ДиалогВыбораФайла.ПолноеИмяФайла;
        Элемент.Доступность = 0;
    КонецЕсли;    
КонецПроцедуры
 
 
 
Процедура АдресДоставкиНачалоВыбора(Элемент, СтандартнаяОбработка)
 
    //СтандартнаяОбработка = Ложь;
 
    __ = ЭлементыФормы.ДанныеФайла.ТекущаяСтрока.Контрагент;
 
    Если __.Пустая() Тогда
        ВвестиЗначение(__, "Выберите контрагента");
    КонецЕсли;
 
    Если НЕ __.Пустая() Тогда
 
 
 
        ЗапросАдреса=Новый Запрос();
        ЗапросАдреса.Текст = "ВЫБРАТЬ
                             |    КонтактнаяИнформация.Представление
                             |ИЗ
                             |    РегистрСведений.КонтактнаяИнформация КАК КонтактнаяИнформация
                             |ГДЕ
                             |    КонтактнаяИнформация.Объект = &ВыбКонтрагент";
        ЗапросАдреса.УстановитьПараметр("ВыбКонтрагент",__);
        ___ = ЗапросАдреса.Выполнить().Выбрать();
 
        ЭлементыФормы.ДанныеФайла.Колонки.АдресДоставки.ЭлементУправления.СписокВыбора.Очистить();
        выбор = ЭлементыФормы.ДанныеФайла.Колонки.АдресДоставки.ЭлементУправления.СписокВыбора;
 
        Пока ___.Следующий() цикл
            выбор.Добавить(___.Представление);
        КонецЦикла;
    КонецЕсли;
КонецПроцедуры
 
 
Процедура КнопкаВыполнитьНажатие(Кнопка)
    // здесь начнем заполнять заявку
    Для каждого Строка Из ДанныеФайла Цикл
        если строка.Выбран = 0 тогда
            продолжить;
        конецесли;
        если строка.Договор.ДоговорИстек тогда
            Сообщить("Отгрузка по договору "+строка.Договор+" не возможна. Он истек");
            продолжить;
        конецесли;
 
        НовыйДокумент= Документы.ЗаказПокупателя.СоздатьДокумент();
        НовыйДокумент.Дата                    = ТекущаяДата();
        НовыйДокумент.АвтоРезервирование      = Истина;
        НовыйДокумент.ВалютаДокумента         = Константы.ВалютаРегламентированногоУчета.Получить();
        НовыйДокумент.ДатаОплаты              = ТекущаяДата()+Строка.Договор.ДопустимоеЧислоДнейЗадолженности;
        НовыйДокумент.ДоговорКонтрагента      = Строка.Договор;
        НовыйДокумент.Комментарий             = "Создан обработкой. Дата "+ТекущаяДата();
        НовыйДокумент.Контрагент              = Строка.Контрагент;
        НовыйДокумент.КратностьВзаиморасчетов = 1;
        НовыйДокумент.КурсВзаиморасчетов      = 1;
        НовыйДокумент.Организация             = Организация;
        НовыйДокумент.амМенеджер              = Строка.Сотрудник;
        НовыйДокумент.Склад                   = Склад;
        НовыйДокумент.СуммаВключаетНДС        = Истина;          
        НовыйДокумент.амТипОплаты              = Строка.ТипОплаты;
        НовыйДокумент.амГлубинаКредита          = Строка.Договор.ДопустимоеЧислоДнейЗадолженности;
 
        НовыйДокумент.ТипЦен                  = Справочники.ТипыЦенНоменклатуры.НайтиПоНаименованию("Розничная");
        НовыйДокумент.УчитыватьНДС=Истина;
        НовыйДокумент.СуммаВключаетНДС=Истина ;
        НовыйДокумент.ИспользоватьПлановуюСебестоимость = истина;
        НовыйДокумент.КурсВзаиморасчетов =1.0;
        НовыйДокумент.КратностьВзаиморасчетов = 1;
        // загрузим табличную часть
 
        для каждого строкаПоиска из ТЗСтрок цикл
            если строкаПоиска.КолонкаВФайле <> строка.КолонкаВФайле тогда
                продолжить;
            конецесли;
            ОбработкаПрерыванияПользователя();
            // код номенклатуры может содержать или не содержать "К"
            // обработаем
            ТЗ = ЗначениеИзСтрокиВнутр(строкаПоиска.ТЗ);
            для каждого товар из ТЗ цикл
                номенклатураК=Справочники.Номенклатура.НайтиПоКоду("К"+товар.Код);
                номенклатура=Справочники.Номенклатура.НайтиПоКоду(товар.Код);
                __ = НовыйДокумент.Товары.Добавить();
                если номенклатураК = Справочники.Номенклатура.ПустаяСсылка() тогда
                    если номенклатура = Справочники.Номенклатура.ПустаяСсылка() тогда
                        сообщить("Не нашли по коду "+товар.Код);
                        продолжить;
                    иначе
                        __.Номенклатура = номенклатура;
                    конецесли;
                иначе
                    __.Номенклатура = номенклатураК;
                конецесли;
                // теперь добавим единицу измерения
                __.Количество = товар.Количество;
                __.ЕдиницаИзмерения = __.Номенклатура.ЕдиницаХраненияОстатков;
                __.Коэффициент = __.ЕдиницаИзмерения.Коэффициент;
                __.СтавкаНДС = __.Номенклатура.СтавкаНДС;
 
                //СтрокаТабличнойЧасти = ЭлементыФормы.Товары.ТекущиеДанные;
                ЗаполнитьЕдиницуЦенуПродажиТабЧасти(__, НовыйДокумент, Константы.ВалютаРегламентированногоУчета.Получить()); 
                // Рассчитать реквизиты табличной части.
                РассчитатьСуммуТабЧасти(__, НовыйДокумент);
                РассчитатьСуммуНДСТабЧасти(__, НовыйДокумент);
            конецЦикла;
        конецЦикла;
        НовыйДокумент.Записать();
        строка.Выбран = 0;
    конеццикла;
 
конецПроцедуры    
 
Процедура ПриОткрытии()
    // Вставить содержимое обработчика.
    ЭлементыФормы.ДанныеФайла.Видимость = Ложь;    
КонецПроцедуры
 
 
Функция convertToURL(FileName)
    __ =  стрзаменить(FileName," ","%20" );
    __ =  стрзаменить(__,"\","/");
    Возврат "file:/" + "/localhost/" + __;
КонецФункции
 
 
ТЗСтрок = новый ТаблицаЗначений;
ТЗСтрок.Колонки.Добавить("КолонкаВФайле");
ТЗСтрок.Колонки.Добавить("ТЗ");