Показать сообщение отдельно
Старый 16.08.2006, 21:36   #13  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Thumbs up А теперь существенно положительный результат
Цитата:
Ибо любой, простите, дурак мог бы подобным образом поступить в своих злодейских целях...
Однако, как выясняется, может… И в злодейских, и в мирных!

Цитата:
Подозреваю, что, возможно, у них предусмотрена, какая-то случайная временная задержка на переключение этой галки "Доверять доступ к Visual Basic Project"
Подозреваю, что ничего такого нет, а есть просто поле ключика в Registry – AccessVBOM.


Что ж, ситуация в целом побеждена. И побеждена так, как мне хотелось – деликатно.

Под «деликатно» я в данном случае понимаю следующий алгоритм:
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();
}
Сей пост можно считать дополнением для темы Axapta программирует Excel на VBA.

Последний раз редактировалось Gustav; 21.08.2006 в 15:45.