![]() |
#10 |
Участник
|
У нас, в основном, работа с Excel происходит в терминальном режиме на бездисковых станциях. Поэтому есть своя специфика. Не знаю, можно ли замеченные проблемы применить к работе собственно на сервере. Тем не менее, перечислю с чем столкнулся и как исправил
Создание новой сессии. Подключение к терминалу. Первый запуск Excel В этот момент буфер обмена вообще не инициализирован. Любая попытка что-то вставить через pasteSpecial(1) заканчивается крахом. Необходима принудительная инициализация буфера обмена. Ну, например, открыть блокнот, что-то там написать, выделить, Ctrl+C, Ctrl+V. Однако тот же процесс инициализации буфера можно сделать и в процессе вставки в Excel. В результате, метод insertText() принимает такой вид X++: // Вставка в ячейку Excel через буфер обмена текстовой информации // Код взят с сайта [url]http://forum.mazzy.ru/index.php?showtopic=385&hl=excel[/url] // Можно вставлять много ячеек одной командной используя управляющие коды перехода по ячейкам // Для перехода на соседние ячейки в теле текста следует использовать коды: // num2char(9) - клавиша Tab - следующая ячейка в текущей строке - символ "\t" // num2char(13) - клавиша Enter - следующая ячейка в первом столбце области _bookMark - символ "\n" public void insertText(BookMark _bookMark, TextBuffer _text, int _workSheet = 1) { COM XLSWorkSheet, XLSrange; TextBuffer tempBuffer, // To store clipboard contents tempBufferDouble; int nextI, maxI = 5; str errorMsg; int errorNum; ; // Если содержимое TextBuffer вообще не введено, то PastSpecial даст ошибку, // а если заведена пустая строка, то нет смысла делать PastSpecial if (! _text.size()) { return; } // Initializing XLSWorkSheet object XLSWorkSheet = this.getWorkSheet(_workSheet); if (!XLSWorkSheet) { throw error("@DIS6043"); } // Initializing XLSRange object XLSrange = this.findRange(_bookMark,_workSheet); if (!XLSrange) { throw error("@SYS27391"); } XLSrange.select(); for (nextI = 1; nextI <= maxI; nextI++) { if (nextI > 1) { sleep(1000); } try { // Storing clipboard contents tempBuffer = new TextBuffer(); tempBuffer.fromClipboard(); // Инициализирую буфер обмена, если он по каким-то причинам не был инициализирован // такое случаяет в момент входа в терминальном режиме, особенно на бездисковых станциях XLSrange.value2("Выделите данную ячейку, нажмите Ctrl+C и повторите выполнение отчета"); XLSrange.copy(); XLSrange.value2(""); // Preparing text to be inserted // Теоретически, данная функция возвращает 0, если вставить не удалось // но фактически, она возвращает результат факта отправки данных в буфер обмена, // а не результат реального попадания этих данных в буфер. Т.е. всегда возвращает 1 _text.toClipboard(); // Поэтому факт реального попадания данных в буфер обмена определяем дополнительно // Эта проверка имеет смысл только для самоконтроля // Все равно будет исключение на pasteSpecial() и по try...catch уйдем на следующий шаг цикла // Inserting text from clipboard XLSWorkSheet.pasteSpecial(COMVariant::createFromInt(1)); // 1 - "Text only" mode // Restoring clipboard contents tempBuffer.toClipboard(); // В случае успеха, прерываю цикл break; } catch (Exception::Error) { // Скорее всего, ошибка будет на pasteSpecial(), т.е. надо восстановить буфер tempBuffer.toClipboard(); // в случае ошибки удаляю последнюю строку infolog, // которая генерится автоматически ошибкой COM if (infolog.line()) { infolog.clear(infolog.line()-1); } // предпринимаю очередную попытку сделать вставку через буфер } } // for (nextI) // Если выход из цикла for произошел "штатно", то значение счетчика будет больше максимально допустимого значения if (nextI > maxI) { if (errorMsg) { error(errorMsg); } throw error("Ошибка при копировании данных через буфер обмена."); } } X++: excel = new ComExcelDocument_RU(); excel.newFile(fileName,true); excel.visible(false); ( Excel ) excel.visible(true); Сразу после открытия файла сделать его видимым, что позволяет инициализировать много чего из очень разных настроек MS Office, тут же сделать не видимым, заполнить данными и снова отобразить. Разумеется, это сопровождается мельканием окна Excel. Но, пока я не нашел других способов однозначно инициализировать буфер обмена. |
|