11.08.2006, 11:00 | #1 |
Участник
|
Вызов Item() для коллекций Excel
AXAPTA 2.5 SP3
Надо при формировании отчета в Excel добавить в сформированный файл некоторую служебную информацию: кто и когда создал отчет. В Excel для этого можно воспользоваться пунктом меню: Файл - Свойства - закладка "Прочие" На уровне объектной модели Excel - это экземпляр коллекции CustomDocumentProperties объекта WorkBook. Для отладки, создаю файл "Пример.xls" записываю в него одно свойство и далее пытаюсь его прочитать: PHP код:
Цитата:
Общий сбой при вызове метода Item' COM-объекта.
Можно ли обойти проблему? Да, с коллекцией BuiltinDocumentProperties (это то, что на закладке "Документ" в свойствах Excel) происходит то же самое. Колекцию "вижу", объекты коллекции - нет. Пробовал с Excel 2000 и Excel 2003 (на разных машинах) - результат одинаковый. AXAPTA 2.5 SP3 |
|
11.08.2006, 12:29 | #2 |
Участник
|
Сталкивался с этим
А если так? X++: static void MVB_Excel_DocProperty(Args _args) { COMExcelDocument_RU excel; FileName fileName = "C:\\Пример.xls"; COM doc; COM app; COM Workbook; COM prj; COM comp; COM module; COM code; str s; #define.vbext_ct_StdModule(1) ; excel = new ComExcelDocument_RU(); excel.newFile(fileName,true); doc = excel.getComDocument(); app = doc.Application(); Workbook = app.ActiveWorkbook(); prj = Workbook.VBProject(); comp = prj.VBComponents(); comp.add(#vbext_ct_StdModule); module = comp.item(comp.count()); code = module.CodeModule(); s = strfmt( "Sub SetDocumentProperties()\n" + "\n" + "ActiveWorkbook.BuiltinDocumentProperties(\"Author\").Value = \"%1\"\n" + "ActiveWorkbook.BuiltinDocumentProperties(\"Creation Date\").Value = CDate(\"%2\")\n" + "With ActiveWorkbook.CustomDocumentProperties\n" + " .Add Name:=\"Автор\", _\n" + " LinkToContent:=False, _\n" + " Type:=msoPropertyTypeString, _\n" + " Value:=\"%1\"\n" + " .Add Name:=\"Дата создания\", _\n" + " LinkToContent:=False, _\n" + " Type:=msoPropertyTypeDate, _\n" + " Value:=CDate(\"%2\")\n" + "End With\n" + "\n" + "End Sub", (select UserInfo where UserInfo.id == curuserId()).Name, date2str(today(), 123, 2, 2, 2, 2, 4) ); code.addFromString(s); app.Run(strfmt("%1.SetDocumentProperties", module.name())); }
__________________
Axapta v.3.0 sp5 kr2 Последний раз редактировалось AndyD; 11.08.2006 в 12:35. |
|
11.08.2006, 14:06 | #3 |
Участник
|
В принципе, работает. Спасибо. Хотя это и напоминает операцию по вырезанию гланд через ж...
|
|
11.08.2006, 14:10 | #4 |
Участник
|
Оно самое
__________________
Axapta v.3.0 sp5 kr2 |
|
11.08.2006, 14:26 | #5 |
Moderator
|
Цитата:
Сообщение от Владимир Максимов
Хотя это и напоминает операцию по вырезанию гланд через ж...
Решение AndyD'а нормальное - по принципу: "разведчиков (шпионов) лучше всего вербовать из жителей той местности, где вы собираетесь производить разведку" |
|
14.08.2006, 15:59 | #6 |
Участник
|
Для информации тем, кто пойдет тем же путем:
1) Все это добро будет работать, если это допускает политика безопасности собственно Excel. Начиная с версии XP это Пункт меню Excel: Сервис \ Макрос \ Безопасность \ Закладка "Надежные издатели" переключатель "Доверять доступ к Visual Basic Project" Если этот переключатель будет выключен, то пользователь будет видет сообщение: Цитата:
Функция VFProject возвратила код ошибки ..., что означает (unknow)
prj = Workbook.VBProject(); 2) Этот код практически один-в-один можно перенести в Word. Естесственно заменив ссылку на рабочую книгу, ссылкой на документ. Причем в Word для элементов коллекции BuiltinDocumentProperties() можно использовать не только названия, но и константы. В Excel соответствующих констант нет, хотя, конечно, можно напрямую писать числа. |
|
14.08.2006, 23:10 | #7 |
Участник
|
В общем, победил я еe (Axapta'у). Сделал на интерфейсах без макросов.
Хотя этот способ можно так-же охарактеризовать как перректальный X++: #define.msoPropertyTypeDate(0x00000003) #define.msoPropertyTypeString(0x00000004) static void AndyD_Excel_DocProperty(Args _args) { COMExcelDocument_RU excel; FileName fileName = ""; COM doc; COM comDocProp, comOneProp; ComVariant var; ComDispFunction funcGet; ComDispFunction funcSet; COMVariant varArg1; COMVariant varArg2; COMVariant varArg3; COMVariant varArg4; COMVariant varRet; ; excel = new ComExcelDocument_RU(); excel.newFile(fileName,true); doc = excel.getComDocument(); // ------------------ Запись в BuiltinDocumentProperties comDocProp = doc.BuiltinDocumentProperties(); funcGet = new ComDispFunction(comDocProp, "Item", COMDispContext::PropertyGet); varArg1 = new COMVariant(COMVariantInOut::In, COMVariantType::VT_BSTR); varArg1.bStr("Author"); varRet = new COMVariant(COMVariantInOut::OUT_RETVAL, COMVariantType::VT_DISPATCH); funcGet.call(varArg1, varRet); comOneProp = COM::createFromInterface(varRet.iDispatch()); funcSet = new ComDispFunction(comOneProp, "Value", COMDispContext::PropertyPut); varRet = new COMVariant(COMVariantInOut::In, COMVariantType::VT_BSTR); varRet.bStr((select UserInfo where UserInfo.id == curuserId()).Name + "-Builtin"); funcSet.call(varRet); // Пример получения значения funcSet = new ComDispFunction(comOneProp, "Value", COMDispContext::PropertyGet); varRet = new COMVariant(COMVariantInOut::Out_retVal, COMVariantType::VT_BSTR); funcSet.call(varRet); info(varRet.bStr()); funcGet = new ComDispFunction(comDocProp, "Item", COMDispContext::PropertyGet); varArg1 = new COMVariant(COMVariantInOut::In, COMVariantType::VT_BSTR); varArg1.bStr("Creation Date"); varRet = new COMVariant(COMVariantInOut::OUT_RETVAL, COMVariantType::VT_DISPATCH); funcGet.call(varArg1, varRet); comOneProp = COM::createFromInterface(varRet.iDispatch()); funcSet = new ComDispFunction(comOneProp, "Value", COMDispContext::PropertyPut); varRet = new COMVariant(COMVariantInOut::In, COMVariantType::VT_DATE); varRet.date(today()); funcSet.call(varRet); // ------------------ Запись в CustomDocumentProperties comDocProp = doc.CustomDocumentProperties(); funcSet = new ComDispFunction(comDocProp, "Add", COMDispContext::Method); varArg1 = new COMVariant(COMVariantInOut::In, COMVariantType::VT_BSTR); varArg1.bStr("Автор"); varArg2 = new COMVariant(COMVariantInOut::In, COMVariantType::VT_BOOL); varArg2.boolean(false); varArg3 = new COMVariant(COMVariantInOut::In, COMVariantType::VT_INT); varArg3.int(#msoPropertyTypeString); varArg4 = new COMVariant(COMVariantInOut::In, COMVariantType::VT_BSTR); varArg4.bStr((select UserInfo where UserInfo.id == curuserId()).Name + "-Custom"); funcSet.call(varArg1, varArg2, varArg3, varArg4); varArg1.bStr("Дата создания"); varArg3.int(#msoPropertyTypeDate); varArg4 = new COMVariant(COMVariantInOut::In, COMVariantType::VT_DATE); varArg4.date(today()); funcSet.call(varArg1, varArg2, varArg3, varArg4); // Пример получения значения funcGet = new ComDispFunction(comDocProp, "Item", COMDispContext::PropertyGet); varArg1 = new COMVariant(COMVariantInOut::In, COMVariantType::VT_BSTR); varArg1.bStr("Автор"); varRet = new COMVariant(COMVariantInOut::OUT_RETVAL, COMVariantType::VT_DISPATCH); funcGet.call(varArg1, varRet); comOneProp = COM::createFromInterface(varRet.iDispatch()); funcSet = new ComDispFunction(comOneProp, "Value", COMDispContext::PropertyGet); varRet = new COMVariant(COMVariantInOut::Out_retVal, COMVariantType::VT_BSTR); funcSet.call(varRet); info(varRet.bStr()); }
__________________
Axapta v.3.0 sp5 kr2 |
|
|
За это сообщение автора поблагодарили: Владимир Максимов (1), Gustav (3). |
15.08.2006, 10:19 | #8 |
Участник
|
Большое спасибо, а то я уже устал объяснять пользователям, что им надо установить птичку в настройках Excel или Word.
Тем более, внедренцы умудрились организовать экспорт в Excel внутри транзакции. В результате, когда VBProject() дает исключение, а Try...Catch это исключение не ловит (точнее, оно игнорируется внутри транзакции) и происходит автоматическое завершение транзакции. Последний способ обходит блокировку VBProject и нет проблем с такой кривой органищацией работы. |
|
15.08.2006, 15:32 | #9 |
Moderator
|
Цитата:
Сообщение от Владимир Максимов
а то я уже устал объяснять пользователям, что им надо установить птичку в настройках Excel или
Word. X++: static void MVB_Excel_DocProperty_2(Args _args) { COMExcelDocument_RU excel; FileName fileName = "C:\\Пример.xls"; COM doc; COM app; COM Workbook; COM prj; COM comp; COM module; COM code; str s; // added by Gustav // ---------------------- COM comTemp; str vbCrLf, alertMessage; // ---------------------- #define.vbext_ct_StdModule(1) ; excel = new ComExcelDocument_RU(); excel.newFile(fileName,true); doc = excel.getComDocument(); app = doc.Application(); // added by Gustav: запрос на проверку доступа к VB-проекту // -------------------------------------------------------- vbCrLf = num2char(13) + num2char(10); alertMessage = 'Нажмите ОК и проверьте на следующем шаге включенность опции' + vbCrLf + '""Доверять доступ к Visual Basic Project"" на закладке ""Надежные издатели""'; app.ExecuteExcel4Macro('ALERT("' + alertMessage + '")'); comTemp = app.CommandBars(); comTemp = comTemp.Item('Macro'); comTemp = comTemp.Controls(); comTemp = comTemp.Item(3); comTemp.Execute(); // -------------------------------------------------------- Workbook = app.ActiveWorkbook(); prj = Workbook.VBProject(); comp = prj.VBComponents(); comp.add(#vbext_ct_StdModule); module = comp.item(comp.count()); code = module.CodeModule(); s = strfmt( "Sub SetDocumentProperties()\n" + "\n" + "ActiveWorkbook.BuiltinDocumentProperties(\"Author\").Value = \"%1\"\n" + "ActiveWorkbook.BuiltinDocumentProperties(\"Creation Date\").Value = CDate(\"%2\")\n" + "With ActiveWorkbook.CustomDocumentProperties\n" + " .Add Name:=\"Автор\", _\n" + " LinkToContent:=False, _\n" + " Type:=msoPropertyTypeString, _\n" + " Value:=\"%1\"\n" + " .Add Name:=\"Дата создания\", _\n" + " LinkToContent:=False, _\n" + " Type:=msoPropertyTypeDate, _\n" + " Value:=CDate(\"%2\")\n" + "End With\n" + "\n" + "End Sub", (select UserInfo where UserInfo.id == curuserId()).Name, date2str(today(), 123, 2, 2, 2, 2, 4) ); code.addFromString(s); app.Run(strfmt("%1.SetDocumentProperties", module.name())); // added by Gustav: удаляем VBA-модуль из рабочей книги // -------------------------------------------------------- comTemp = module.Collection(); comTemp.Remove(module); // -------------------------------------------------------- } |
|
15.08.2006, 15:56 | #10 |
Участник
|
При всем уважении, но, боюсь, пользователи после первого десятка показов станут бить ногами.
__________________
Axapta v.3.0 sp5 kr2 |
|
15.08.2006, 16:11 | #11 |
Участник
|
Цитата:
Сообщение от Gustav
За Word не скажу, а в Excel'е - если вот так попробовать?
|
|
16.08.2006, 00:38 | #12 |
Moderator
|
Отрицательный результат - тоже результат
Пытался поиграться радикально-хацкерским сочетанием Exception + SendKeys. Не покатило. Т.е. катит, но случайным образом, через раз-два, иногда наполовину. Для использования, конечно, не рекомендуется, хотя, если бы катило устойчиво, то было бы прикольно.
С другой стороны, если бы катило, то Microsoft пришлось бы изобретать новую рогатку для борьбы с таким управлением доступа к VB Project. Ибо любой, простите, дурак мог бы подобным образом поступить в своих злодейских целях... Подозреваю, что, возможно, у них предусмотрена, какая-то случайная временная задержка на переключение этой галки "Доверять доступ к Visual Basic Project", подразумевающая именно ручное (неторопливое) переключение. Поэтому программа, как умалишенная сбрасывающая и устанавливающая этот флажок втечение долей секунды, просто отдыхает... На память все же выкладываю джоб-попытку как отчет о проведенном исследовании: X++: static void MVB_Excel_DocProperty_3(Args _args) { COMExcelDocument_RU excel; FileName fileName = "C:\\Пример.xls"; COM doc; COM app; COM Workbook; COM prj; COM comp; COM module; COM code; str s; // added by Gustav // ---------------------- COM comTemp; str vbCrLf, alertMessage; int langID; str strSendKeys; boolean useTrustAccessDefault; #define.msoLanguageIDUI(2) // ---------------------- #define.vbext_ct_StdModule(1) ; excel = new ComExcelDocument_RU(); excel.newFile(fileName,true); doc = excel.getComDocument(); app = doc.Application(); // added by Gustav: запрос на проверку доступа к VB-проекту // -------------------------------------------------------- comTemp = app.LanguageSettings(); langID = comTemp.LanguageID(#msoLanguageIDUI); // язык интерфейса Excel switch (langID) { case 1033: strSendKeys = '%TMS%T%V~'; // английский Excel (латинские буквы в стринге) break; case 1049: strSendKeys = '%ЕМБ%Н%В~'; // русский Excel (русские буквы в стринге) break; } useTrustAccessDefault = true; try { // если в исходном состоянии галка "Доверять доступ" выключена, то здесь возникает ошибка comTemp = app.VBE(); } catch (Exception::Error) { useTrustAccessDefault = false; // корректируем ошибку установкой галки app.SendKeys(strSendKeys, true); } // -------------------------------------------------------- Workbook = app.ActiveWorkbook(); prj = Workbook.VBProject(); comp = prj.VBComponents(); comp.add(#vbext_ct_StdModule); module = comp.item(comp.count()); code = module.CodeModule(); s = strfmt( "Sub SetDocumentProperties()\n" + "\n" + "ActiveWorkbook.BuiltinDocumentProperties(\"Author\").Value = \"%1\"\n" + "ActiveWorkbook.BuiltinDocumentProperties(\"Creation Date\").Value = CDate(\"%2\")\n" + "With ActiveWorkbook.CustomDocumentProperties\n" + " .Add Name:=\"Автор\", _\n" + " LinkToContent:=False, _\n" + " Type:=msoPropertyTypeString, _\n" + " Value:=\"%1\"\n" + " .Add Name:=\"Дата создания\", _\n" + " LinkToContent:=False, _\n" + " Type:=msoPropertyTypeDate, _\n" + " Value:=CDate(\"%2\")\n" + "End With\n" + "\n" + "End Sub", (select UserInfo where UserInfo.id == curuserId()).Name, date2str(today(), 123, 2, 2, 2, 2, 4) ); code.addFromString(s); app.Run(strfmt("%1.SetDocumentProperties", module.name())); // added by Gustav: удаляем VBA-модуль из рабочей книги // -------------------------------------------------------- comTemp = module.Collection(); comTemp.Remove(module); if (!useTrustAccessDefault) { // восстанавливаем исходное состояние галки "Доверять доступ" (т.е. выключенное) app.SendKeys(strSendKeys, true); } // -------------------------------------------------------- } |
|
16.08.2006, 21:36 | #13 |
Moderator
|
А теперь существенно положительный результат
Цитата:
Ибо любой, простите, дурак мог бы подобным образом поступить в своих злодейских целях...
Цитата:
Подозреваю, что, возможно, у них предусмотрена, какая-то случайная временная задержка на переключение этой галки "Доверять доступ к Visual Basic Project"
Что ж, ситуация в целом побеждена. И побеждена так, как мне хотелось – деликатно. Под «деликатно» я в данном случае понимаю следующий алгоритм: 1. Перед нашей операцией прописывания свойств читаем текущее состояние этой опции «Доверять доступ к Visual Basic Projects», запоминаем ее в переменную, после чего принудительно включаем. 2. Открываем Excel, выполняем собственно операцию прописывания свойств в файле Excel «кодом VBA» из Аксапты, после чего закрываем Excel. 3. После закрытия Excel восстанавливаем состояние галки из переменной. Три метода основного процесса в джобе ниже соответствуют трём вышеперечисленным шагам. Добытые опытным путем нюансы: 1. Программное закрытие Excel в джобе важно - в противном случае 3-й шаг не имеет смысла, поскольку значение ключа в Regisrty будет перепрописано позже при закрытии Excel вручную, а в нём-то как раз галка и включена нами же на шаге 2. 2. До тех пор, пока все три шага были в едином джобе без деления на методы, шаг 3 также не имел эффекта. После разделения на методы всё получилось. 3. Есть мнение, что нюанс 2 зависит от того, где определена переменная COMExcelDocument_RU excel – во вложенном методе или в общем джобе. Получается, что для достижения эффекта на шаге 3, время жизни переменной excel должно быть ограничено рамками вложенного метода MVB_Excel_DocProperty (excel.finalize() в общем джобе не спасал). Впрочем, если деликатность не сильно важна, а интересует только возможность врубить опцию, то это уже пожалуйста – без всяких нюансов. Я проверял на Excel 2003 – для этой версии в имени ключа содержится подстрока «11.0». Соответственно, для Excel 2002 будет «10.0», для Excel 2000 – безразлично, так как там еще нет опции «доверять доступ». X++: static void MVB_Excel_DocProperty_4(Args _args) { #WINAPI int trustAccess; int key; container con; void Process_Registry_Before() { // запоминание состояния флажка перед стартом Excel key = WinAPI::regOpenKey(#HKEY_CURRENT_USER, @'Software\Microsoft\Office\11.0\Excel\Security', #KEY_QUERY_VALUE); if (key) { con = WinAPI::regGetValue(key, 'AccessVBOM'); WinAPI::regCloseKey(key); trustAccess = conPeek(con,1); } // включение флажка - разрешаем доступ к VBProjects key = WinApi::regOpenKey(#HKEY_CURRENT_USER, @'Software\Microsoft\Office\11.0\Excel\Security', #KEY_WRITE); if (key) { WinApi::regSetValueEx(key, 'AccessVBOM', #REG_DWORD, 1); WinApi::regCloseKey(key); } } void Process_Registry_After() { // восстановление состояния флажка до запуска Excel key = WinApi::regOpenKey(#HKEY_CURRENT_USER, @'Software\Microsoft\Office\11.0\Excel\Security', #KEY_WRITE); if (key) { WinApi::regSetValueEx(key, 'AccessVBOM', #REG_DWORD, trustAccess); WinApi::regCloseKey(key); } } void MVB_Excel_DocProperty() // самый первый вариант AndyD'а { COMExcelDocument_RU excel; FileName fileName = "C:\\Пример.xls"; COM doc; COM app; COM Workbook; COM prj; COM comp; COM module; COM code; str s; // added by Gustav // ---------------------- COM comTemp; FileName newFileName = "C:\\ПримерLAST.xls"; // ---------------------- #define.vbext_ct_StdModule(1) excel = new ComExcelDocument_RU(); excel.newFile(fileName,true); doc = excel.getComDocument(); app = doc.Application(); Workbook = app.ActiveWorkbook(); prj = Workbook.VBProject(); comp = prj.VBComponents(); comp.add(#vbext_ct_StdModule); module = comp.item(comp.count()); code = module.CodeModule(); s = strfmt( "Sub SetDocumentProperties()\n" + "\n" + "ActiveWorkbook.BuiltinDocumentProperties(\"Author\").Value = \"%1\"\n" + "ActiveWorkbook.BuiltinDocumentProperties(\"Creation Date\").Value = CDate(\"%2\")\n" + "With ActiveWorkbook.CustomDocumentProperties\n" + " .Add Name:=\"Автор\", _\n" + " LinkToContent:=False, _\n" + " Type:=msoPropertyTypeString, _\n" + " Value:=\"%1\"\n" + " .Add Name:=\"Дата создания\", _\n" + " LinkToContent:=False, _\n" + " Type:=msoPropertyTypeDate, _\n" + " Value:=CDate(\"%2\")\n" + "End With\n" + "\n" + "End Sub", (select UserInfo where UserInfo.id == curuserId()).Name, date2str(today(), 123, 2, 2, 2, 2, 4) ); code.addFromString(s); app.Run(strfmt("%1.SetDocumentProperties", module.name())); // added by Gustav // -------------------------------------------------------- // удаляем VBA-модуль из рабочей книги comTemp = module.Collection(); comTemp.Remove(module); // сохраняем новый файл Excel if (WinAPI::fileExists( newFileName )) WinAPI::deleteFile( newFileName ); Workbook.SaveAs( newFileName ); // закрываем файл, выходим из Excel excel.closeDocument(); app.Quit(); // -------------------------------------------------------- } //====================================================================== // основной процесс Process_Registry_Before(); MVB_Excel_DocProperty(); Process_Registry_After(); } Последний раз редактировалось Gustav; 21.08.2006 в 15:45. |
|
17.08.2006, 17:12 | #14 |
Участник
|
Строго говоря, в моем случае, приведенный код решением вообще не является, поскольку предполагает обязательно создание файла Excel на диске еще до его отображения. По ряду причин - это сделать невозможно.
Однако за подсказку посмотреть в реестре спасибо. Как-то забыл о такой очевидной вещи. Мелкие добавления: Можно автоматизировать анализ версии Excel. Правда, для этого надо создать экземпляр Excel PHP код:
В результате и получим "9.0", "10.0" или "11.0". Соответсвенно, можно сделать анализ на необходимость контроля. Удалить созданный модуль можно командой PHP код:
|
|
17.08.2006, 19:09 | #15 |
Moderator
|
Скромно-забавный способ задания свойств
Цитата:
Сообщение от Владимир Максимов
Надо при формировании отчета в Excel добавить в сформированный файл некоторую служебную информацию: кто и когда создал отчет.
В Excel для этого можно воспользоваться пунктом меню: Файл - Свойства - закладка "Прочие" Код при этом получается до безобразия компактным - всё делается одной командой: X++: static void MVB_Excel_DocProperty_5(Args _args) { COMExcelDocument_RU excel; COM doc; COM app; str s; str Title = 'Наше Название'; str Subject = 'Наша ""рогатая"" Тема'; str Author = 'Наш Автор (МЫ)'; str Keywords = 'Наши Ключевые слова'; str Comments = 'Наши Заметки'; ; excel = new ComExcelDocument_RU(); excel.newFile('',true); doc = excel.getComDocument(); app = doc.Application(); s = strfmt('SUMMARY.INFO?("%1","%2","%3","%4","%5")', Title, Subject, Author, Keywords, Comments); app.ExecuteExcel4Macro(s); } Можно считать эту "назойливость", также как и ограниченность набора пятью полями, платой за компактность кода. Хотя, с другой стороны, не вижу в этом ничего плохого - пользователю может даже понравиться это финальное "одобрение", тем более, что он может добавить информацию и в другие поля (и вот для их сохранения ему уже придется нажать на OK). Теоретически существует еще команда "SUMMARY.INFO" (без "?"), предназначенная как раз для скрытого прописывания, но она почему-то не производит желаемого эффекта. Не знаю, почему. Возможно, это ограничение метода ExecuteExcel4Macro в свете современной борьбы с макровирусами (в самом Excel 4.0 10 лет назад всё работало хорошо ) Если кто заинтересуется (а там есть кое-что любопытное), то можно скачать: Excel 2000 Help File: Running Excel 4.0 Macros. |
|
17.08.2006, 19:47 | #16 |
Moderator
|
Цитата:
Сообщение от Владимир Максимов
Строго говоря, в моем случае, приведенный код решением вообще не является, поскольку предполагает обязательно создание файла Excel на диске еще до его отображения. По ряду причин - это сделать невозможно.
Если же наша цель - только не напрягать пользователя лишним сообщением о необходимости ВКЛЮЧИТЬ эту галку, то всё замечательно. Главное - включить ее перед запуском инстанса Excel, относящегося именно к нашей задаче. Потом - да и фиг с ней, с включенной. Если же всё же не хочется оставлять пользователя надолго со включенным состоянием по соображениям вирусной безопасности, то галку можно сбрасывать в каком-нибудь пакетном режиме, например, при включении компа или при очередном запуске Аксапты на клиенте - главное, чтобы в этот момент в системе не было ни одной запущенной копий Excel. |
|
Теги |
excel |
|
|