Имя: Пароль:
1C
1С v8
ActiveDocument Word API Множественный вывод макета
, ,
0 beholder13
 
26.11.14
16:08
Доброго времени суток, коллеги.
Есть макет MSWord (ActiveDocument) во внешней печатной форме, из одного листа, есть вывод его как из одного набора данных, так и из нескольких. С одним работает хорошо, с несколькими криво. Причина мне ясна, но толковой инфы по апи нагуглить не получается, поэтому прошу помощи местных богов.

Процедура ВывестиДанныеПоДокументуВШаблонMSWord(ДокументСсылка)
    // Итак, получаем макет, инициализируем ворд:

    Идентификатор = ИдентификаторМакетаВХранилищеЗначений();
    Макет = ПолучитьИзВременногоХранилища(Идентификатор);

    Попытка
        MSWord = Макет.Получить();
    Исключение
        Сообщение = Новый СообщениеПользователю;
        Сообщение.Текст = "Не найден MS Word.";
        Сообщение.Сообщить();
    
        Возврат;
    КонецПопытки;

    // получение данных из базы (в переменную ДокументСсылка может прийти ссылка на документ,
    // массив ссылок на документ или список значений, функция ПолучитьДанныеДляПечати()
    // собирает данные из регистров в структуру со статичным набором ключей для каждого
    // документа, на который придет ссылка):

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

    // вывод в макет осуществляется как через execute, так и через docvariable:

    Попытка
        Документ = MSWord.Application.Documents(1);
        MSWord.Application.Options.CheckSpellingAsYouType = False;
          MSWord.Application.Options.CheckGrammarAsYouType = False;
        
        // Если пришло несколько наборов параметров, кладем шаблон в буфер обмена
        Если МассивПараметров.Количество() > 1 Тогда
            Документ.Activate();
            MSWord.Application.Selection.WholeStory();
            MSWord.Application.Selection.Copy();    
        КонецЕсли;        
        
        Для каждого СтруктураПараметров Из МассивПараметров Цикл
            Замена = Документ.Content.Find;
            РезультатСклонения = "";
            Замена.Wrap = 1;

            // Здесь подставляются значения для замены, свернул в одну строку для читабельности
            Замена.Execute("ТекстЗамены",,,,,,,,,СтруктураПараметров.ТекстЗамены,2);
            
            // Здесь подставляются значения переменных, тоже свернул
            MSWord.Variables("ИмяПеременной").Value = СтруктураПараметров.ИмяПеременной;
            // Собственно говоря, проблема здесь - замены на новом листе прекрасно отрабатывают, не затрагивая предыдущих,
            // тогда как переменные множатся, и заменяются на уровне всего документа, т.е. на всех листах появляется информация с последнего набора

            MSWord.Fields.Update();
            
            // Если несколько наборов, рисуем еще одну страницу
            Если МассивПараметров.Количество() > 1 И НЕ(МассивПараметров.ВГраница() = МассивПараметров.Найти(СтруктураПараметров)) Тогда
                MSWord.Application.Selection.EndKey(6);
                MSWord.Application.Selection.InsertBreak(7);                
                MSWord.Application.Selection.Paste();    
            КонецЕсли;
        КонецЦикла;
        
        // Дальше не важно
        MSWord.Application.Visible = True;
        
        MsWord.Application.Activate();
        
        wdWindowStateMaximize=1;
        wdWindowStateMinimize=2;
        MsWord.Application.WindowState = wdWindowStateMinimize;
        MsWord.Application.WindowState = wdWindowStateMaximize;
    Исключение
        Сообщение = Новый СообщениеПользователю;
        Сообщение.Текст = ОписаниеОшибки();
        Сообщение.Сообщить();
        
        MSWord.Application.Quit();
    КонецПопытки;
КонецПроцедуры

Вопрос: как подставлять значения в доквериэйблы на новых листах так, чтобы не затрагивать значения на предыдущих? Как вариант - как уникализировать имена копируемых переменных?
Заранее спасибо.
1 beholder13
 
26.11.14
16:09
придти, прошу прощения
2 beholder13
 
26.11.14
17:01
Ап
3 Гёдза
 
26.11.14
17:06
так ты прям в макете проставляешь переменные?
Тогда открывай каждый раз макет заново
4 beholder13
 
26.11.14
17:12
(3) Не прокатит, мне в один документ надо несколькими листами вывести, а открытие макета заново => инициализация нового процесса ворда
5 Jaap Vduul
 
26.11.14
17:48
Апдейтить не все поля документа, а только на новых разделах.
Или после очередного апдейта разрывать связь полей, которые не должны больше обновляться, с источниками.
6 Гёдза
 
26.11.14
17:50
тогда выделяй блок и делай замену только выделеном блоке.
Замена = Док.Selection.Find
7 beholder13
 
26.11.14
17:50
(5) а можно, пожалуйста, то же самое, только функциями апи?
8 beholder13
 
26.11.14
17:52
(6) Замена все норм, она же заменяет уже заменяемый текст, так что потом заменяется только то, что нужно заменить) проблема в docvariable, у которых имена дуплятся на уровне всего документа, а у селекшена я не нашел дочерних объектов-вэриэйблов
9 beholder13
 
26.11.14
17:53
От docvariable не уйти - там большой текст собирается по кускам, тупо не влазит в замену по широте.
10 beholder13
 
26.11.14
17:55
(5) вообще идея хорошая, я так понимаю, после апдейта отрезать имеющиеся переменные, и тогда потом паста положит новые, без дубликатов, вопрос лишь в том, как это на васике звучит)
11 Jaap Vduul
 
26.11.14
18:40
12 beholder13
 
26.11.14
18:44
(11) благодарю за помощь =)