2016-10-03 94 views
6

Co chcę zrobić:PowerShell: Usuń moduł VBA z programu Excel plik

  • otworzyć pliku Excela
  • Dynamiczne importowanie moduł VBA i uruchomić funkcję z modułu
  • Wyjmij moduł

Więc tutaj jest mój kod PowerShell:

$excel = New-Object -ComObject Excel.Application 
$excel.Workbooks.Open($filepath) | Out-Null 
$macro = $excel.ActiveWorkbook.VBProject.VBComponents.Import($MacroFilepath) 
$Excel.ActiveWorkbook.Application.Run("HoursSumCounter.main") | Out-Null 
$excel.ActiveWorkbook.VBProject.VBComponents.Remove($macro) 

(Naturalnie włączony dostęp do projektu VBA w ustawieniach Centrum zaufania programu Excel, aby móc importować moduł dynamicznie)

teraz błędu, który jest wyświetlany jest następujący:

Cannot find an overload for "Remove" and the argument count: "1". 
At line:1 char:1 
+ $excel.ActiveWorkbook.VBProject.VBComponents.Remove($macro) 
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    + CategoryInfo   : NotSpecified: (:) [], MethodException 
    + FullyQualifiedErrorId : MethodCountCouldNotFindBest 

ten Cała sprawa faktycznie działa, jeśli robię to w Excelu (bez powłoki powershell).

Ale o to, co się dowiedziałem już ...

Sprawdziłem przeciążenie funkcji usunięcia:

[DBG]: PS C:\Users\MUT2BP\Desktop\recefice>> $excel.ActiveWorkbook.VBProject.VBComponents.Remove 

OverloadDefinitions                                           
-------------------                                           
void Remove(Microsoft.Vbe.Interop.VBComponent VBComponent)                                  
void _VBComponents.Remove(Microsoft.Vbe.Interop.VBComponent VBComponent)                              
void _VBComponents_Old.Remove(Microsoft.Vbe.Interop.VBComponent VBComponent) 

Okazało się, że rzeczywiście należy przekazać obiekt typu Microsoft.Vbe.Interop.VBComponent VBComponent jednak moja $macro obiekt jest typu System.__ComObject#{eee00921-e393-11d1-bb03-00c04fb6c4a6}

[DBG]: PS C:\Users\MUT2BP\Desktop\recefice>> $macro | Get-Member 


    TypeName: System.__ComObject#{eee00921-e393-11d1-bb03-00c04fb6c4a6} 

Name   MemberType Definition       
----   ---------- ----------       
Activate  Method  void Activate()     
DesignerWindow Method  Window DesignerWindow()   
Export   Method  void Export (string)   
... 

... choć ac Remove funkcji tual zwraca typ VBComponent, podczas tego procesu automatyzacji OLE zostaje przekonwertowany na obiekt COM.

Podejrzewam, że muszę jakoś przekonwertować ten obiekt COM na rzeczywisty obiekt VBComponent, ale nigdy nie mogę go wyraźnie rzucić.

+0

Nie mogę tego powtórzyć - Twój kod działał poprawnie z przykładowym skoroszytem i modułem. – Comintern

+0

Czy masz zainstalowane narzędzia MS Office Developer Tools? – Comintern

+0

@Comintern Hmm, nie jestem tego świadomy. W dodawaniu/usuwaniu programów i funkcji (panel ctrl) nie widzę czegoś takiego. Jakieś inne miejsce, w którym mógłbym to sprawdzić? – ThomasMX

Odpowiedz

0

czy istnieje powód, dla którego nie można po prostu odwołać się do odpowiedniego modułu? excel nie wymaga dołączania modułów. moduły w dodatkach & osobiste skoroszytów można uruchomić na dowolnym arkuszu.

jeśli tworzysz dodatek (zapisz jako _ dodatek, a następnie w narzędziach programistycznych kliknij to pole, aby go włączyć) csn zaktualizuj go w locie z dowolnym modułem.

jeśli nie masz dostępu do zakładki Narzędzia dla programistów, można dodać moduł do osobistego skoroszytu (jest to ukryty skoroszyt, które mogą być generowane automatycznie, gdy najpierw użyć rekordu makro przycisk)

wykonując w dowolnym z powyższych możesz otworzyć plik Excela, uruchomić na nim kod, a następnie zamknąć plik bez kłopotów z próbą programowego dodania modułu do podwyżki, która nie obsługuje modułów.

jeśli koniecznie musisz dołączyć i usunąć moduł, spróbuj tego: otwórz plik, przekonwertuj do formatu xlsb, zamknij plik, zmień nazwę pliku na .zip, dodaj moduł i zaktualizuj ścieżkę xml do pliku .zip, zmień nazwę na .xlsb otwórz w programie Excel, uruchom moduł, zapisz jako plik, który nie obsługuje modułów.

0

musiałem zrobić coś podobnego ostatnio, tak jak to zrobiłem.

$Code = @' 
your code here 
Make sure this guy is public 
@' 

$Excel = new-object -com Excel.Application 
#Need to change security settings 

New-ItemProperty -Path ` 
"HKCU:\Software\Microsoft\Office\$($Excel.Version)\excel\Security" -Name ` 
AccessVBOM -Value 1 -Force | Out-Null 

New-ItemProperty -Path ` 
"HKCU:\Software\Microsoft\Office\$($Excel.Version)\excel\Security" -Name ` 
VBAWarnings -Value 1 -Force | Out-Null 

$Workbook = $Excel.Workbooks.open("Insert Path to file here",$true) 
$xlModule = $Workbook.VBProject.VBComponents.Add(1) 
$Module = $xlmodule.CodeModule.AddFromString($Code) 
$Excel.Run("Name of Module here, make sure that the sub is public") 
$Workbook.VBProject.VBComponents.Remove($xlmodule) 
$Workbook.Close($True) 
Powiązane problemy