Как добавить код VBA в excel.Worksheet в powershell?
Мне нужно включить Private Sub **Worksheet_BeforeDoubleClick** (ByVal Target As Range, Cancel As Boolean)
в моем листе (1).
Я могу правильно открывать и писать в ячейки, но не знаю, как поместить код VBA в таблицу (а не в модуль VBA).
$excel = New-Object -ComObject Excel.Application
$workbook = $excel.Workbooks.Add()
$worksheet = $workbook.WorkSheets.item(1)
$worksheet.range("c1","g6").value = "str"
...
$workbook.SaveAs($xlFlie, 50)
$Excel.Application.Quit()
Я попробовал это:
$xlmodule = $workbook.VBProject.VBComponents.Add()
$xlmodule.CodeModule.AddFromString($code)
Но я получил эту ошибку:
Can not call a method in an expression Null.
Au caractère .\Build-ADGrpsMembers2Excel.ps1:273 : 5
+ $xlmodule = $workbook.VBProject.VBComponents.Add(1)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation : (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
1 ответ
Решение
Мне нужно изменить параметр VBA на
$excel = New-Object -ComObject Excel.Application
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
мой рабочий код:
$excel = New-Object -ComObject Excel.Application
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.Add(1)
$worksheet=$workbook.WorkSheets.item(1)
$excel.Visible=$true
$excel.DisplayAlerts = $true
$excel.ScreenUpdating = $true
#$worksheet.range("c1","f6").ColumnWidth = 4
#$worksheet.range("c1","f6").Orientation = 90
$xlmodule = $workbook.VBProject.VBComponents.item('feuil1')
$code = @"
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
End Sub
"@
$xlmodule.CodeModule.AddFromString($code)
$saveName = "$([Environment]::GetFolderPath('desktop'))\Export-Excel ($( ((Get-Date -Format u ) -replace ":", ".") -replace "Z", '' ) ).xlsb"
# savegarde du fichier
$workbook.SaveAs($saveName, 50)
Write-Verbose "Closing $($WorkSheetName)"
$Excel.Workbooks.Close()
Write-Verbose "Exit Excel"
$Excel.Application.Quit
Этот ответ мне очень помог, но мне пришлось добавить еще один модуль, поэтому я сделал что-то вроде этого
$workbook.VBProject.VBComponents.Add(1)
$workbook.VBProject.VBComponents.Add(2)
$workbook.VBProject.VBComponents.Add(3)
1 - для модуля, 2 - для пользовательской формы, 3 - для класса
чтобы захватить только что добавленный модуль, он будет на последнем месте в массиве компонентов
$arrayOfComponents = @($workbook.VBProject.VBComponents)
$justAddedModule = $arrayOfComponents[$arrayOfComponents.Length-1]
так это выглядит примерно так
$excel = New-Object -ComObject Excel.Application
$vbaProject = new-object -ComObject VB
$FilePath = "c:\temp\excel.xlsm"
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.Add($FilePath)
# Add(1) za dodavanje modula
#$workbook.VBProject.VBComponents.Add(1)
$xlmodule = $workbook.VBProject.VBComponents.item('Module1')
$code = @"
Sub test()
'
End Sub
"@
$xlmodule.CodeModule.AddFromString($code)
$workbook.SaveAs($FilePath,52)
$excel.Workbooks.Close()
$excel.Application.Quit()