Как отключить слияние экземпляров Excel?

#excel

#excel

Вопрос:

В последних версиях Excel появилась новая функция, при которой Excel игнорирует запрос на новый сеанс, если обнаруживает, что он уже запущен. Я хочу знать, как это остановить.

В этой статье службы поддержки Майкрософт предлагается добавить параметр реестра

 ComputerHKCUSoftwareMicrosoftOffice16.0ExcelOptionsDisableMergeInstance = 1
 

но у меня это не сработало. Могут ли другие пользователи проверить, работает ли это для них, и сообщить?

Тем временем я обнаружил, что, удерживая нажатой клавишу ALT при запуске нового экземпляра Excel, появляется диалоговое окно с надписью «Вы хотите запустить новый экземпляр Excel? (Да / Нет)», это показано в этой статье Microsoft. На данный момент это хороший обходной путь, но я бы хотел, чтобы настройка реестра работала.

Комментарии:

1. Вы можете запустить Excel с параметром /x, чтобы открыть его как новый экземпляр. Excel.exe /x

2. @Sebastian: круто. Работает для меня. Спасибо.

3. Я видел то же поведение, что и вы, и внезапно оно было исправлено, но после последнего обновления оно снова перестало работать. Очень неприятно, что это не может быть обработано последовательно с течением времени.

Ответ №1:

Вот альтернативный путь … если он вам полезен.

большой поклонник блога, кстати!

 Option Explicit

Private Declare Function IIDFromString Lib "ole32" (ByVal lpszIID As Long, IID As Any) As Long

Private Declare Function CoCreateInstance Lib "ole32" (rclsid As Any, ByVal pUnkOuter As Long, _
    ByVal dwClsContext As Long, riid As Any, ByVal ppv As Long) As Long

Private Declare Sub RtlMoveMemory Lib "kernel32" (pDst As Any, pSrc As Any, ByVal dlen As Long)

Private Const CLSID_EXCELAPP    As String = "{00024500-0000-0000-C000-000000000046}" ' Excel COM object GUID.

Private Const IID_DISPATCH      As String = "{00020400-0000-0000-C000-000000000046}" 'IDispatch Interface GUID.

Private Const IID_NULL          As String = "{00000000-0000-0000-0000-000000000000}"


Private Type GUID
    data1                       As Long
    data2                       As Integer
    data3                       As Integer
    data4(7)                    As Byte
End Type



Private Const CLSCTX_LOCAL_SERVER   As Long = amp;H4

Private Const S_OK                  As Long = amp;H0
Private Const E_NOINTERFACE         As Long = amp;H80004002
Private Const REGDB_E_CLASSNOTREG   As Long = amp;H80040154
Private Const CLASS_E_NOAGGREGATION As Long = amp;H80040110
Private Const E_POINTER             As Long = amp;H80004003

Sub CreateNewExcelInstance()
    Dim ExcelClassID        As GUID
    Dim IID                 As GUID
    Dim ObjectPtr           As Long
    Dim ExcelIIDHandle      As Long

    ExcelIIDHandle = IIDFromString(StrPtr(CLSID_EXCELAPP), ExcelClassID)
    If ExcelIIDHandle <> 0 Then Exit Sub

    ExcelIIDHandle = IIDFromString(StrPtr(IID_DISPATCH), IID)
    If ExcelIIDHandle <> 0 Then Exit Sub

    ExcelIIDHandle = CoCreateInstance(ExcelClassID, 0, CLSCTX_LOCAL_SERVER, IID, VarPtr(ObjectPtr))

    Debug.Print ExcelIIDHandle = S_OK

'''''''''''''''''''''''''
'
'    -> If you want the second instance to be visible:
'
'               Dim SecondExcelInstance as Object
'
'               RtlMoveMemory SecondExcelInstance, ObjectPtr, 4
'
'               SecondExcelInstance.Visible = True
'               SecondExcelInstance.Workbooks.Add
'
'''''''''''''''''''''''''''''''''''''''''''''''''''''''
End Sub
 

Комментарии:

1. Хорошо, я попробую это. Спасибо за добрые слова о блоге.

2. Я счел полезным иметь альтернативу VBA, поскольку она предоставляет недорогой способ подключения к некоторому базовому многопоточному или асинхронному поведению без необходимости развертывания каких-либо дополнительных библиотек DLL