Выгрузка в word c
В статье приведена инфраструктура Windows Forms проекта, в котором Microsoft Word воспринимается приложением в качестве шелла. В статье раскрыты несколько интересных моментов использования Composite UI Application Block, в частности подключение инфраструктуры доменной модели Word в сервисам расширения каркаса, а так же приведены некоторые факты и особенности разработки с использованием средств VSTO.
Задача
Предположим, у нас есть несколько десятков людей, которые пишут документы и постоянно работают с их редакциями. Sharepoint и другие порталы по каким-то причинам не подходят, поэтому требуется реализация собственной бизнес-логики. Усложним задачу — люди работают в области, очень далекой от компьютерной тематики и хорошо знают только пакет Microsoft Office. Еще усложним — контора бедная, Microsoft Office у большинства народа версии 2003-ей. Кое где, у больших начальников и Главного босса стоит 2007ой. Парк машин разнородный — начиная от 2000-ой винды и до Windows Vista.
Решение
А к чему все это?
(Это кому не терпиться узнать, чем все закончится). На выходе я выложу Visual Studio solution, который позволит в полпинка создать свое приложение, подключаемое в Microsoft Word. По ходу дела я объясню практически все, что и как в этом солюшене используется.
Что потребуется для работы
- Microsoft Word 2003 SP3
- Visual Studio 2005 или 2008
Зачем CAB?
Для того, чтобы определить явное разделение функционала, связанного с Microsoft Word от простой Windows Forms логики. Проще говоря, наш плагин будет являться модулем CAB, и при желании, мы легко сможем подключить эту логику в другие приложения CAB. Еще проще говоря, использование CAB минимизирует количество glue-кода.
Есть еще две причины, по которым я включил CAB в решение. Первая состоит в том, что я уже давал описание этого каркаса здесь, а теперь хочу привести полноценный работающий пример. Вторая причина более банальная — мне нравится CAB, он делает мир и вещи в нем проще:)
Подробнее про VSTO
- Уровень документа (Document Level Customization)
- Уровень приложения (Application Level Customization)
Если кто заинтересовался возможностями VSTO — очень много про них есть в msdn.
Псевдозадача
Создадим маленький пример, иллюстрирующий все вышесказанное. Пусть есть требование, согласно которому пользователь может выделять текст из документа Microsoft Word и получать этот выделенный текст в окошке пользовательского элемента (знаю, дурацкий пример, но более сложного делать не хочется, а менее сложный уже трудно придумать).
Более подробно. Пользователь запускает Microsoft Word. После запуска среди тулбаров пользователю будет доступен ТР — тулбар расширения (т.е., нашего расширения). На нем находится кнопка, по нажатию которой пользователю показывется окно с кнопкой «Получить текст» и элементом управления multiline textbox. Пользователь нажимает на кнопку «Получить текст», выделенный в документе текст копируется в textbox. Все счастливы.
Понятно, что для жизни пример малопригоден. Но создаваемая инфраструктура позволит довольно просто нарастить на него «мускулы», если это, конечно, кому-то потребуется.
Создание solution
После установки VSTO в студии при создании нового solution станут доступны Office проекты:
Будьте аккуратны с названием — оно одновременно будет являться названием root namespace и поменять его можно будет только ручками через выгрузку проекта.
На выходе получается солюшен с двумя проектами:
WordCAB — это, собственно, add-in. Второй — не менее важный, это deployment проект для модуля расширения. Почему он важен?
Дело в том, что установка модуля расширения на рабочие станции пользователей — весьма трудоемкая затея. Она заключается не только в том, чтобы просто скопировать библиотеки в нужную папку. Для успешного фукнционирования модуля требуется прописать кучу ключей в реестр. Если копнуть глубже, получается, что модуль расширения подключается к Microsoft Office как COM-библиотека, со всеми вытекающими. Кому интересно, все нужные ключи реестра можно поглядеть в deployment-проекте (Нажать правой кнопкой, View->Registry).
В классе ThisAddIn находится точка доступа в модуль:
private void ThisAddIn_Shutdown( object sender, System. EventArgs e)
>
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InternalStartup()
this .Startup += new System.EventHandler(ThisAddIn_Startup);
this .Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
>
* This source code was highlighted with Source Code Highlighter .
В ThisAddIn_Startup будем писать код. Если быть точнее, будем запускать CAB-приложение.
Что такое CAB-приложение?
Это класс такой. В нем есть точка запуска — метод Run() , и некоторая инфраструктура каркаса — в частности, имеются доступ к главному прецеденту «Приложение» (т.е., к основному, рутовому WorkItem) и возможности переопределить системные сервисы, добавляемые в приложения по-умолчанию. Этот класс уже реализован в базовом виде, а программисту требуется параметризировать его — указать тип рутового прецедента и тип главной формы:
internal sealed class AddInApplication : WindowsFormsApplication
protected override void Start()
>
>
* This source code was highlighted with Source Code Highlighter .
В качестве типа главной формы (шелловой формы), указан object. Почему? Потому что приложение запускается в Microsoft Word, поэтому необходимости создавать главную форму нет. Форма Microsoft Word и есть главная форма, правда, без традиционных для нее возможностей.
По ходу пьесы мне пришло в голову немного прояснить модель приложения для модуля расширения в Microsoft Word.
Модель приложения Word Add-in
Итак, пользователь работает с документами. Более того, в единицу времени он может работать только с одним документом. Поэтому модуль расширения имеет четкий контекст — текущий открытый документ. (Кстати, в модели Microsoft Word VSTO этот документ обозначен как Globals.ThisAddIn.Application.ActiveDocument ). Отсюда (я сделал) вывод (или упрощение) — показывать пользовательские бизнес-элементы имеет смысл в модальном режиме, поскольку в ином случае нарушается контекст. Элементы управления, открытые для одного документа, должны существовать только во время активности этого документа.
Пример — пользователь открыл документ и открыл его карточку (не в модальном режиме). Переключился на другой документ, а карточка осталась для предыдущего — нарушение контекста и целостности восприятия. Разумеется, подобное поведение контролировать можно (и даже нужно, в некоторых случаях), но модальность элементов управления и жесткая их привязка к текущему активному документу делает жизнь проще.
Modal Workspace
Пользовательские элементы управления в каркасе CAB показываются в специальных так называемых рабочих зонах (Workspace). Согласно описанному выше поведению, нам требуется показывать элементы управления в модальном режиме. Поскольку родной CAB-овский WindowWorkspace оказался дубоват и выглядит некрасиво, я написал простенький свой — приводить код не буду, потому что его пара-тройка экранов. Насладиться творчеством можно скачав solution с кодом (ссылка на архив приведена в конце статьи).
Workspaces.Add(( new SimpleModalWorkspace() ), WorkspaceNames.MainWorkspace);
* This source code was highlighted with Source Code Highlighter .
Итого: под ключем-идентификатором WorkspaceNames.MainWorkspace зарегистрировали модальную рабочую зону. Доступиться до нее теперь можно откуда угодно, где есть ссылка на главный прецедент: запрос интерфейса IWorkspace из коллекции Workspaces по указанному выше ключу. Все просто, как апельсин! (с) х/ф «Терминатор 2»
Фабрика элементов управления Microsoft Word
Речь пойдет о тулбаре Word и кнопках на нем. В VSTO это обертки над COM-объектами — CommandBar и CommandBarButton из пространства имен Microsoft.Office.Core . Жутко глючные штуки, если честно, особенно их анимация. Понять все тонкости и детали удалось только после ударного троллинга на форумах VSTO.
В чем идея — идея состоит в том, чтобы избавить программиста и разработчиков бизнес-модулей от необходимости работать с COM-обертками. Для этого, мы (то есть, я) интегрируем модель Misrosoft Word в механизм так называемых мест расширения (UiExtensionSite) каркаса CAB.
- В массив тулбаров Microsoft Word вставляется тулбар
- В коллекцию кнопок на тулбаре вставляется кнопка
- В кнопку уже ничего не вставляется (не рассматриваем случае комбобоксов, хотя они присутствуют), поэтому это терминальный объект
- IWordCommandBarContainer — контейнер тулбаров Microsoft Word
- IWordCommandBar — контейнер кнопок на тулбаре
- IWordButton — кнопка
К слову сказать, помимо определения элементов управления Word конкретные типы интерфейсов IWordCommandBar и IWordButton являются адаптерами к упомянутым выше CommandBar и CommandBarButton соответственно.
Для того, чтобы каркас понял, что, куда и, главное, каким образом вставлять, ему необходимо зарегистировать фабрику адаптеров для пользовательских элементов управления. В нашем случае, вставлять можно тулбары (в коллекцию тулбаров) и кнопки (в коллекцию кнопкок на тулбаре). Поэтому, регистрировать фабрику адаптеров нужно для IWordCommandBarContainer и для IWordCommandBar . Потом, когда пользователь будет получать место расширения, каркас будет искать инстансы классов добавления подчиненных элементов для этого места расширения, после чего использовать их по назначению — добавлять элементы. Ну а чтобы не заморачиваться, эти инстансы порождаются фабрикой:
public class CommandBarUIAdapterFactory : IUIElementAdapterFactory
public IUIElementAdapter GetAdapter( object uiElement)
if ( uiElement is IWordCommandBarContainer ) //тулбары
return new CommandBarUIAdapter(( IWordCommandBarContainer )uiElement);
if ( uiElement is IWordCommandBar ) //кнопки в тулбарах
return new CommandBarButtonUIAdapter(( IWordCommandBar )uiElement);
throw new ArgumentException( "uiElement" );
>
public bool Supports( object uiElement)
return ( uiElement is IWordCommandBarContainer ) || ( uiElement is IWordCommandBar );
>
>
* This source code was highlighted with Source Code Highlighter .
А вот реализация коллекции тулбаров (с возможностью добавить новый!)
private object _null = System.Reflection.Missing.Value;
* This source code was highlighted with Source Code Highlighter .
С кнопками на тулбарах аналогично. Гляньте код на досуге.
Пришлось, к слову, создавать фабрику самих кнопкок и тулбаров (см. IWordUIElementFactory ). Дело в том, что модули CAB работают с интерфейсами IWordCommandBar и IWordButton . Конкретные типы этих интерфейсов находятся в сборке VSTO Word-AddIn и завязаны на Microsoft.Office.Core . Поэтому, чтобы в модулях (где отсутствует ссылка на Office) была возможность получать инстансы указанных элементов, создается фабрика. Она регистрируется в главном WorkItem.
Services.AddNew();
IUIElementAdapterFactoryCatalog factoryService = base .Services.Get();
factoryService.RegisterFactory( new CommandBarUIAdapterFactory());
UIExtensionSites.RegisterSite(UIExtensionSiteNames.WordBarsSite, new BarCollection());
* This source code was highlighted with Source Code Highlighter .
Если вы запутались, извините:) Я сам понимаю, что тут без поллитры не разберешься. (Если подебажиться, то многое становится понятным.)
Модуль CAB
Это обычная сборка. В ней должен быть класс ModuleInit . В этом классе есть ссылка на главный прецедент AddInWorkitem и, как следствие, есть доступ ко всему добру, про которое я писал выше.
Задача модуля CAB такова — подгрузиться к главному преценденту, вставить тулбар, вставить кнопку на него, описать обработчик кнопки:
UIExtensionSite site = _rootWorkItem.UIExtensionSites[UIExtensionSiteNames.WordBarsSite];
IWordCommandBar mainBar = site.Add(_factory.CreateBar( "AddInToolbar" ));
IWordButton btn = _factory.CreateButton(mainBar, CommandNames.OpenForm, ToolStripItemDisplayStyle.ImageAndText, "Открыть окно" ,
"Открыть форму просмотра Custom Control" , Resources.OpenForm, false );
mainBar.AddButton(btn);
btn.Click += new EventHandler(ButtonClick);
* This source code was highlighted with Source Code Highlighter .
Обработчик кнопки будет создавать пользовательское окно с кнопкой «получить текст» и текстовым полем, после чего показывать его (применив специальный модификатор показа WindowSmartPartInfo ) в ранее упомянутой рабочей зоне (которую, как мы помним, я зарегистрировал в прецеденте под ключем WorkspaceNames.MainWorkspace ):
private void ButtonClick( object sender, WordButtonClickArgs e)
object smartPart = _rootWorkItem.SmartParts.AddNew();
WindowSmartPartInfo info = new WindowSmartPartInfo();
info.FormStartPosition = FormStartPosition.CenterScreen;
info.MaximizeBox = false ;
info.MinimizeBox = false ;
info.Resizable = false ;
info.Title = "Custom Control" ;
info.ShowInTaskbar = false ;
_rootWorkItem.Workspaces[WorkspaceNames.MainWorkspace].Show(smartPart, info);
>
* This source code was highlighted with Source Code Highlighter .
Подгрузка модуля
Здесь я сделал финт коленом. Обычно модули подгружаются в каркас через специальный декларативный формат подгрузки — так называемый ProfileCatalog. Обычно, это хороший способ подключить все, что нужно. Но, учитывая суровые советские реалии, имеется ненулевая вероятность того, что программисту потребуется недекларативная логика подключения модуля. Для этого мы будем переопределять специальный сервис перечисления подгружаемых модулей — IModuleEnumerator . Я сделал его очень простым — он глядит в папку исполняемой сборки и ищет в ней модуль под названием CustomModule.dll. Находит, и подгружает. Ну, или не подгружает, если не находит:
public IModuleInfo[] EnumerateModules()
List result = new List ();
string path = GetModulePath(ModuleName);
if ( File .Exists(path) )
result.Add( new ModuleInfo(ModuleName));
return result.ToArray();
>
* This source code was highlighted with Source Code Highlighter .
Сейчас эта служба очень простая, но при желании, разумеется, в нее можно нагородить хоть черта лысого. Например, подгружать модули из базы данных:)
Перегрузить эту службу нужно в классе приложения CAB:
protected override void AddServices()
base .AddServices();
* This source code was highlighted with Source Code Highlighter .
Доктор, я устал. Что получилось?
Получилось то, что задумывалось в изначальном псевдопримере:
В тулбарах Microsoft находится наш тулбар, на нем висит кнопка с иконкой, по событию нажатия кнопки вылезает пользовательский элемент управления, в текстовое поле которого с помощью кнопки можно загнать выделенный в документе текст:) Тривиально, но обратите внимание, как ничтожна связность между объектами! Хочется подметить, что у каркаса, при должном обращении, идеальная code maintainability.
Внимание! Подводные камни!
Security
The operation you are performing will alter security policy.
Are you sure you want to perform this operation? (yes/no)
yes
Added union code group with "-url" membership condition to the User level.
Success
Вместо "D:\Projects\WordCAB\bin\Debug\*" нужно указать папку, из которой производится запуск Add-in. Не забудьте про звездочку.
Add-in перестал загружаться!
Иногда, когда в модуле возникает необработанный Exception, Word блокирует исполнение этого модуля при следующей загрузке. Зайдите Help->About->Disabled Items и посмотрите, нет ли в списке вашего расширения. Если есть, уберите его оттуда. При следующем Run-Debug он появится.
Как убрать
Удаление расширения не такое тривиальное. Вытащите кнопку COM-AddIns на тулбар Microsoft Word. Для этого надо зайти в Tools->Customize->Tools->(Drag'n'Drop)COM-AddIns. Кликните на нее и снимите галку с вашего расширения. Он выгрузится. Чтобы заново подгружать, наоборот, выставите галку обратно. Другой способ — зайти в панель управления и удалить из программ.
А что с Word 2007?
Add-in замечательно подгружается в Ribbon на последнюю вкладку.
Там еще кучка мелких подводных камней. Но я тут и так уже настолько много написал, что не уверен, что кто-нибудь до конца дочитает:)
Где взять код
Выводы
Я ведь это уже делал, но хрен теперь найдешь тот кусок кода, гуглим снова… Где бы найти простое и понятное руководство для начинающего, а не тонкости для мега-гуру?
Рубрики
Свежие записи
Свежие комментарии
Архивы
1. Подключить нужные библиотеки
2. Открыть шаблон Word
3. Найти в нем нужное место
4. Вставить в него строку с информацией
1. Проект в студии у нас уже должен быть. В разделе Ссылки/References кликаем правой кнопкой, идем в "Добавить ссылку" и ищем Microsoft.Office.Interop.Word. В параметрах добавленной библиотеки ставим true в Копировать локально/Copy local, так как библиотеку надо копировать вместе с исполняемыми файлами проекта.
В код добавляем соответствующие using
2. Теперь вам предстоит провести много времени с замечательным интерфейсом Word, который представляет сам текстовый редактор и его потроха в виде разнообразных обьектов. Сейчас важны два - Application и Document. Переменные для них по ряду не очевидных причин лучше объявлять через интерфейсы.
Так же почти все функции Word требуют объектных параметров, даже если внутри них сидят простые строки и логические значения, так что лучше заранее сделать несколько оберток
Чтобы запустить Word и открыть в нем шаблон с диска (путь известен), потребуется примерно такой код
Принципиально важны два момента
1. Мы создаем неуправляемый ресурс, который не соберет сборщик мусора - отдельный процесс в памяти с приложением Word, если мы его не закроем и не выведем на экран, он так и останется там висеть до выключения компьютера. Более того такие ворды могут накапливаться незаметно для пользователя, программист-то еще прибьет их вручную. Заботиться о высвобождения неуправляемого ресурса должен программист.
2. По умолчанию Word запускается невидимым, на экран его выводим мы.
Для начала рассмотрим самый простой и примитивный вариант - поиск и замена строки в документе Word. Некоторые программисты так и работают - ставят в шаблон текстовую метку вроде @@nowDate и заменяют ее на нужное значение.
Пришло время познакомится с фундаментом работы с Word - великим и ужасным объектом Range. Его суть сложно описать словами -это некоторый произвольный кусок документа, диапазон (range), который может включать в себя все что угодно - от пары символов, до таблиц, закладок и прочих интересных вещей. Не стоит путать его с Selection - куском документа, выделенным мышкой, который само собой можно конвертировать в Range. Соотвественно нам надо получить Range для всего документа, найти нужную строку внутри него, получить Range для этой строки и уже внутри этого последнего диапазона заменить текст на требуемый. И не стоит забывать, что документ может иметь сложную структуру с колонтитулами и прочей ересью, возможный универсальный метод для замены всех вхождений данной строки:
На самом деле это не самый лучший метод для вставки информации в документ, так как могут возникнуть сложности с уникальными именами для текстовых меток (если текст одной входит в начало другой, данный метод найдет ее и заменит), их совпадением с произвольным текстом и так далее.
Даже если нам надо найти (и например отформатировать) именно строку с текстом внутри документа, лучше всего выдать наружу найденный Range и уже с ним производить разные злодеяния. Получим примерно такой метод:
Простейшее решение проблемы уникальности текста (нужно нам найти Range слова Word, но внутри всего документа оно встречается десятки раз) - искать строку внутри строки, сначала найти уникальную строку, потом не уникальную внутри нее, неэстетично, но дешево, надежно и практично.
Если строку надо просто заменить, то сойдет простейшее
Но так как Range является универсальный контейнером для любого куска документа Word, то его возможности неизмеримо шире, часть их будет рассмотрена в дальнейших заметках.
Если нам надо просто встать в начало документа (и что-то вставить уже туда):
Имеется база данных содержащая информацию об абонентах. Абонентам должны отсылаться бумажные письма. Тексты писем (шаблоны) готовят люди от ИТ очень далекие (юристы, маркетологи и прочие дармоеды), но умеющие пользоваться вордом в том или ином виде (иногда, даже очень хорошо). Т.е. объяснить им, как вставить ключевое слово в текст, вполне возможно, но более сложное требование вызовет у них когнитивный диссонанс.
Второй момент, есть необходимость некоторые письма перед печатью подвергать ручной проверке и правке при необходимости (UPD) и находится в одном файле (это связано, с механизмами их дальнейшей передачи). Т.е. в месте формирования они только готовятся (и иногда печатаются).
Казалось, что задача проста как три копейки: берем шаблон, вставляем его в выходной документ, заменяем ключевые слова, повторяем до конца записей. Не прокатило. Письмо может содержать несколько страниц, и при таком подходе, торможение ворда при росте объема документа приводит к тому, что рассылка на 30 писем может формироваться до часа. Пришлось включать голову и думать.
//загружаем ключевые слова
string [] keyWords = < "FNAME" , "LNAME" , "DEBT" , "MR" >;
//Ищем позиции ключевых слов в документе и добавляем в список
List keyWordEntries= new List();
for ( int i=0; iforeach ( string keyWord in keyWords)
if (sdoc.Words[i+1].Text.Trim()==keyWord)
keyWordEntries.Add( new keyWordEntry(keyWord,i+1,sdoc.Words[i+1].Text.Remove(0,keyWord.Length)));
>;
>;
>;
* This source code was highlighted with Source Code Highlighter .
Тут же обнаруживаются первые приколы работы с вордом (точнее они в этом тексте первые, а в процессе изысканий они были почти последнии): массивы элементов документов (Words, Paragraphs, ets) нумеруются с единицы; пробелы стоящие после слова, ворд легко может считать частью слова – пришлось писать логику их сохранения.
Создаем выходной документ на основе шаблона, так мы малой кровью можем получить документ с нужной разметкой страницы, колонтитулами, стилями и т.п.
_Document ddoc = word.Documents.Add( ref template, ref oMissing, ref oMissing, ref oMissing);
//Удаляем из него всё наполнение
ddoc.Range( ref oMissing, ref oMissing).Delete( ref oMissing, ref oMissing);
* This source code was highlighted with Source Code Highlighter .
for ( int i = 0; i < rowCount; i++)
ddoc.Range( ref oMissing, ref oMissing).InsertParagraphAfter();
>;
* This source code was highlighted with Source Code Highlighter .
И начинаем заполнять от конца к началу, чем получаем бешенный прирост скорости, т.к. обращаемся по индексу параграфа, а не ищем каждый раз конец документа. Само заполнение выглядит следующим образом (sdoc – временный документ, в который подставляем значения, ddoc – тот который должен получится):
for ( int i = rowCount; i > 0; i--)
if (i < rowCount)
ddoc.Paragraphs[i].Range.InsertParagraphAfter();
ddoc.Paragraphs[i + 1].Range.InsertBreak( ref pageBreak);
>;
//подставляем слова во временный документ
foreach (keyWordEntry ke in keyWordEntries)
string replaceWith = "" ;
switch (ke.keyword)
//тут логика подстановки
default :
replaceWith = ke.keyword+ke.spacesAfter;
break ;
>;
sdoc.Words[ke.position].Text = replaceWith;
>;
sdoc.Range( ref oMissing, ref oMissing).Copy();
ddoc.Paragraphs[i].Range.Paste();
>
* This source code was highlighted with Source Code Highlighter .
По-существу всё, осталось сохранить полученный документ и корректно завершить процесс ворда.
Еще пару слов в догонку: символы '.', ',', '*' и все остальные, ворд считает отдельным словом и если вам нужно вставит, например, дату, то логика слегка усложнится.
Все началось с того, что стал писать простенькую программу, которая должна была выполнять функции телефонного справочника. В качестве основного компонента, в котором будут размещаться все данные, выбрал объект класса ListView. Но любая хорошая программа должна уметь сохранять все свои данные в отдельный файл, с последующей его загрузкой, для продолжения работы с данными.
Что бы не изобретать велосипед, я принял решение о сохранение данных в XML-файл. Такой тип файла, очень удобен и популярен у многих разработчиков, с ним легко работать. Единственным его недостатком является слабая защищенность данных. Его можно открыть любым простым редактором текста, хотя и можно применить шифрование текста — это не гарантирует полной безопасности для информации в файле.
Как осуществить экспорт данных?
Как видно из скриншота, в элементе меню «Файл» уже все заготовлено для Экспорта и Импорта нашей телефонной книги, осталось написать сам код.
Адаптивный код
Такой способ очень хороший, при условии, когда мы лично пишем класс объекта, с которым будем работать. А как быть в тех случаях, когда мы использует уже готовый класс? К примеру, класс ListView или Datagridview, мы их не писали (лично), но многие из нас часто ими пользуются.
В этот момент, я понял, что нужно создавать свой класс который, я всегда смогу использовать. Так мне не нужно (в будущем) все время тратить на описывание различных параметров. Нужно лишь будет переопределить методы класса, или просто сделать правки.
Класс для работы с XML
Для работы данного класса потребуется подключить еще две сборки:
Класс я решил назвать "Stroka", это потому что мы в цикле будем перебирать все строки нашей таблице. Также обратите, что во всех частях кода описывается по 4 элемента. Это сделано намеренно. Количество элементов должно совпадать с нашим количество колонок, в таблице.
Так как наш класс готов, то мы можем его свернуть в нашем проекте, и больше в него не заглядывать.
Красивый экспорт (сохранение)
Давайте не будем спешить закончить нашу работу. А напишем еще несколько строчек кода, которые позволят нам вызывать диалоговое окно для сохранения.
Это окно мы сможем вызвать вот таким кодом:
Как вы могли заметить, это уже метод экспорта данных в XML-файл. Но здесь ничего интересного не происходит, только вызывается окно для экспорта, и его путь записывается в переменную "filename". Это обычная строковая переменная, которая создается еще в начале проекта.
Выглядит это так:
Сам экспорт выполнится в методе «Export();».
Время метода «Export();»
Важно заметить, что большая часть этого кода «шаблонна», для многих наших проектов с этим классом, единственной отличительной чертой всегда будет наш «цикл перебора всех элементов». Он будет отличаться в зависимости от того, с какой «таблицы» мы будем экспортировать данный. В данном случае, данные берутся с объекта класса ListView.
Обратите внимание на строчки:
Мы создаем объект класса (нашего) Stroka, и в его метод Main помещаем элементы строки (4-х наших колонок).
Экспорт завершен
Созданный XML-файл я открыл программой «Блокнот», и мы можем сравнить структуру файла с нашим кодом.
Наш класс позволяет также импортировать данные, в наше приложение. Мы также сможем редактировать, и выполнять любую другую работу с ними так, как будто данные изначально были в программе.
Рассмотрим два способа выгрузить данные из программы 1С 8.3 в Word. Эти способы можно использовать в альтернативу стандартных внутренних и внешних печатных форм 1С. Пример обработки, который описывается в статье, можно скачать здесь.
Кстати, в новой версии 1С Бухгалтерия появилась возможность настройки пользовательских шаблонов договоров без программирования.
Выгрузка данных из 1C в шаблон Word (Active document)
Чтобы сформировать документ в формате Word, нужно сначала подготовить шаблон. А точнее, создадим макет с типом «Active document» для примера во внешней обработке:
Затем выбираем объект, например, Microsoft Office Word 97-2003:
Откроется чистый документ Word (причем в конфигураторе).
А в документе Word будем расставлять закладки. С закладками работать приятней и быстрей.
Если вы только начинаете программировать в 1С или просто хотите систематизировать свои знания - попробуйте Школу программирования 1С нашего друга Владимира Милькина. Пошаговые и понятные уроки даже для новичка с поддержкой учителя.
Попробуйте бесплатно по ссылке >>
Выбираем режим закладок и расставляем:
Прописываем такую процедуру:
Создание документа Word сразу (Word.Application)
Документ Word можно создать в 1C без использования макета. Напрямую, с помощью COM объекта. Делается это не сложнее.
После запуска кода мы видим вот такую красивую картину:
Ссылка на скачивание обработки — Выгрузка в Word.
Если Вы начинаете изучать 1С программирование, рекомендуем наш бесплатный курс (не забудьте подписаться на YouTube — регулярно выходят новые видео):
Читайте также: