Печать MS Word документа из командной строки

Обычно для пользователя при формировании различного рода документов в формате MS Word формировались файлы и просто открывались.

Для этого вызывалась процедура host и передавалась строчка запуска.

Например, фрагмент кода

cmd  := 'cmd /c start winword.exe "'||pi_fname||'"';
host(cmd);

Однако возникла задачка массовой печати. Т.е. есть подготовленные файлы, и их надо, например, при нажатии на кнопку распечатать на принтере. Естественно, пользователь не должен открывать, печатать, закрывать каждый документ.

В итоге вызов видоизменился до следующего


cmd  := 'cmd /c start /wait winword.exe "'||pi_fname||'" /q /n /mFilePrintDefault /mFileSave /mFileExit';
host(cmd);

Что добавилось

  • start /wait – дает нам возможность запустить приложение и ждать его завершения. В нашем случае мы должны в определенном порядке получать на принтере документы, т.е. они должны и попадать в очередь последовательно, а без ожидания маленькие документы могут встать в очередь быстрее
  • далее пойдут параметры уже непосредственно для MS Word
  • /q – не показывать окно заставки (splash screen)
  • /n – не создавать новый документ (new default document)
  • /m – выполнение макроса (runs a macro [/mmacroname])
  • /mFilePrintDefault – печать на принтере по умолчанию
  • /mFileSave – сохранение документа
  • /mFileExit – закрытие документа

Сначала все работало без параметра сохранения документа, но почему-то некоторые документы при открытии получали статус измененных и, соответственно, при закрытии выводился запрос на сохранение. Его нам не надо получать, т.к. процесс печати приостанавливается; соответственно, добавляем сохранение.

Все равно это изменение только локальной временной копии документа, т.к. сам документ хранится в базе данных и только выгружается на клиентскую машину при просмотре или печати.

Если же использовать такой вызов не в рамках данный задачи, а например, просто использовать его для печати документов из командной строки, то, лучше выкинуть параметр /mFileSave из строки вызова.

 

Работа с CLOB, улучшение производительности

Этот пост может пригодиться, если работаем с LOB-объектам в базе данных Oracle.
Предыстория:
Есть динамически сформированные XML-документы, которые хранятся в Global Temporary Table (GTT), и которые хочется сконвертировать в CLOB и сохранить в базе.
Это реальный пример, документы – это MS Excel или MS Word документы, сформированные с использованием возможностей MS Office формировать документы с использованием WordML и XML Spreadsheet.

Continue reading “Работа с CLOB, улучшение производительности”

Oracle Developer 6i: Forms – Questions

Периодически получаются переходы на мой сайт по запросам по Oracle Forms.

Если есть желание – задавайте вопросы 🙂

Могу попробовать ответить практически на все вопросы, но только не FFI, т.к. в проектах избегаю его использования. Да и в трех-уровневой модели он будет проблематичен 🙂

SMTP+attached files vs Antivirus

Ура, одержана победа 🙂 противостояния антивируса и передачей почтового сообщения с прикрепленными файлами средствами SMTP.

Предыстория

Давно создал пакет в СУБД Oracle, который использует UTL_SMTP для отправки из базы писем. Все работало отлично, пока на одном из проектов письмо пришло некорректным, а именно: приаттаченный файл имел неправильное имя, расширение .dat и не раскодированным.

Иными словами: когда мы посылаем письмо, то прикрепляем файлы посредством перекодировки в base64. Например, средствами шаблона мы генерируем какой-нибудь отчет или документ (например, в MS Excel или MS Word), полученный CLOB кодируем в base64 и вставляем в письмо. Отсылаем. Получатель получает письмо, которое содержит прикрепленный документ. Так вот, когда получатель открывает письмо, то в аттаче у него оказывается кодированный в base64 текст документа 🙁

Решение

Все оказалось просто до банальности :).

При отправке с почтового сервера, письмо проверялось антивирусом, установленным на нем (ну, в нашем случае был Касперский). И он добавлял свои пять копеек в заголовок, что приводило к пролеме.

Как оказалось виной всему было то, что при формировании строка

Content-Disposition: attachment; filename="test.xls"

была разнесена на 2 строки 🙂

Content-Disposition: attachment;
filename="test.xls"

и до момента, пока мы не встретились с антивирусом, это не было столь критичным для почтового сообщения.

Метод наименьших квадратов

Век живи – век учись.
За 15 лет первый раз потребовалось работать со статистикой :). В проекте для планирования и прогнозирования потребовалось обрабатывать данные за предыдущие годы для формирования прогноза на следующий.
Для реализации выбраны две методики – среднее значение, и значение, полученное методом наименьших квадратов. Вот тут и задумался, как реализовать вторую методику, насколько “зависнет” дальнейшая разработка, пока буду реализовывать само решение метода. Однако, какое облегчение – все давно реализовано в самой СУБД (SQL Language Reference):
REGR_ (Linear Regression) Functions
The linear regression functions are:

  • REGR_SLOPE
  • REGR_INTERCEPT
  • REGR_COUNT
  • REGR_R2
  • REGR_AVGX
  • REGR_AVGY
  • REGR_SXX
  • REGR_SYY
  • REGR_SXY

Первых двух функций как раз достаточно. Единственное, надо обратить внимание на результат, если в выборке одна пара значений – вернется NULL, и это правильно. Тогда, например, можно взять для прогноза то же значение, что и в выборке.

Удаление Oracle Database под Windows

Возникла необходимость удалить базу данных Oracle 11g из-за сбоя при установки (в смысле сбой не при установке самой базы, а при некорректных шагах по интеграции).
Выяснились нюансы 🙂

Beginning with 11.2, the Oracle Universal Installer will no longer be used to remove Oracle software from an environment. A new Deinstall tool is shipped with the Oracle Products and is also available for download on OTN

Это из нотки “How to Manually Remove Oracle Server Software on Microsoft Windows Platforms (Doc ID 1069034.1)”

Continue reading “Удаление Oracle Database под Windows”

Проблема с кодовыми страницами

Навеяло 😉 перестановкой машины у коллеги

Имеем Windows XP (возможны варианты)

После установки машины с чистого листа поехали шрифты в Oracle Forms, выражается в кракозябрах при выводе сообщений (Alerts) на русском языке.

Раньше лечили через Font Substitution (если правильно помню 🙂 ключ в реестре)

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontSubstitutes

Но как уже упоминал, было это давно. Потом был найден на просторах интернета 🙂 другой способ, т.к. проблемы были не только с Oracle Forms.

Это решение – меняем значения для кодовых страниц

  • HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage
  • HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Nls\CodePage
  • HKEY_LOCAL_MACHINE\SYSTEM\ControlSet002\Control\Nls\CodePage

Изменяемые строковые параметры

Параметр Старое значение Новое значение
1250 c_1250.nls c_1251.nls
1252 c_1252.nls c_1251.nls

После чего перегружаем машину и наслаждаемся 😛 отсутствием проблем с кодировкой.

Сегодня пессимизм в настроении :(

Поэтому будем о плохом.

Наверное надо перечитать документацию (концепции и прочее по Oracle 11g), может что изменилось, и гуру, приближенные к исходникам базы рекомендуют писать код иначе.
Итак, начнем.

Кто научил писать в PL/SQL так:

select count(*)
into cnt
from <таблица / список таблиц>
where <различные условия>;

if cnt > 0
then
…..
else
…..
end if;

Ведь есть курсоры. Всего дополнительно 3-4 строчки, но, блин, полный контроль и управление над ситуацией. Нет необходимости отлавливать исключения, я так понимаю из-за этого здесь используют count(*). Есть возможность передавать параметры в запрос, и т.д.
Можно ведь:

declare
cursor c_sel is
select 1
from <таблица / список таблиц>
where <различные условия>;
tmp_n number;
begin
Open c_sel;
Fetch c_sel into tmp_n;
if c_sel%Found
then
Close c_sel;
....
else
Close c_sel;
....
end if;
end;

И зачем нам число строк, если надо только признак есть-нет записи.
Можно ведь использовать и exists. Зачем всю таблицу перебирать; а если там миллионы строк, а не пару сотен тестовых 🙂

Потом получается

почему у меня формирование документа идет 2-3 минуты, вместо 10 секунд

обработка данных занимает 20 минут

ну и в том же духе…

Реестр под 64-разрядной Windows

Реестр 64-разрядных версий Windows подразделяется на 32- и 64-разрядные разделы.

Большинство 32-разрядных разделов имеют те же имена, что и их аналоги в 64-разрядном разделе, и наоборот.

В 32-разрядной Windows приложения обращаются к ключам реестра

HKEY_LOCAL_MACHINE\SOFTWARE\<company>\<product>

В 64-разрядной Windows когда 32-разрядные приложения обращаются к реестру

HKEY_LOCAL_MACHINE\SOFTWARE\<company>\<product>

они на самом деле обращаются к ветке

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\<company>\<product>

По умолчанию в 64-разрядных версиях Windows используется отображение (“registry reflector”) 32-разрядных разделов в узле WOW6432Node. Процесс отображения прозрачен для 32-разрядных приложений, т.е. они могут получать доступ к разделам реестра так, как будто бы они работали в 32-битном окружении несмотря на то, что данные хранятся в другом месте.

Наблюдалась особенность отражения в 64-разрядный ключ: если очищалось значение ключа в 32-разрядной ветке, по какой-то причине не происходил автоматический сброс этого значения в 64-разрядной ветке.

Создание документов с помощью шаблонов (.dot) в MS Office 2007 и MS Office 2010

В самых первых проектах формирование MS Word документов было организовано с использованием OLE-технологии (использовался Office XP).

Это удобно: создаем шаблон (.dot), а дальше программно создаем документ на основании этого шаблона и подставляем в него необходимые данные.

Соответственно, шаблоны хранятся на сети, в определенной папке.

При переходе на MS Office 2007 возникла проблема: не формировался документ на основании шаблона. Было выяснено, что виной всему было наличие в вызове полного пути к шаблону.

Решилась данная проблема настройкой самого MS Word, для этого в настройках MS Word переопределяем путь к шаблонам (где на сети лежат .dot-файлы)

  • Открываем MS Word
  • Создаем пустой документ
  • Нажимаем кнопку “Office”
  • Выбираем «Параметры Word»
  • Выбираем «Дополнительно»
  • Нажимаем кнопку «Расположение файлов…»
  • Изменяем путь к общим шаблонам
  • Успешно выходим
  • Если будет выводиться ошибка о невозможности прочитать/записать шаблон Normal.dotm, то надо указать/изменить на локальную папку путь для пользовательских шаблонов (C:\Documents and Settings\…\My Documents)
  • Возможно, надо будет запустить MS Word и выйти из него, при этом шаблон Normal.dotm автоматически создастся в текущей папке пользовательских шаблонов.

После чего при вызове убираем путь к шаблону.

В MS Office 2010:

  • Открываем MS Word
  • Создаем пустой документ
  • Переходим на закладку «Файл»
  • Выбираем «Параметры»
  • Выбираем «Дополнительно»
  • далее как описано выше