【PowerShell】 Excel을 읽고 쓰기

11702 단어 ExcelPowerShell

소개



PowerShell에서도 거의 VBA와 같은 쓰기로 Excel 편집을 할 수 있다.
정확하게는 .NET Framework를 사용하여 COM 객체를 조작할 수 있다는 것이지만, 그 구문이 거의 VBA와 같기 때문에, VBA와 비슷한 감각으로 기술할 수 있다고 생각한다.

PowerShell로 작성하는 이점



버전 관리가 쉬워집니다.



VBA는 Excel 파일에 내장되어 있고, 그 Excel 파일(xlsx)은 바이너리 형식이라고 하는 것도 있어, VBA의 버전 관리가 곤란한 것은 문제가 되고 있다.
그것을 해결하기 위해 Excel 파일에서 VBA 스크립트를 내보내 버전 관리를 쉽게하기위한 도구도 공개되어있다.
vbac에서 엑셀 VBA 소스 코드를 Git 버전 관리하는 방법
그러나, PowerShell이라면 텍스트 형식 그 자체이므로, 간편하게 버전 관리를 실시할 수 있다.

일괄 처리에 적합



야간에, 사내 시스템으로부터 출력된 csv 파일을 Excel에 받아들여 두고 싶다… 등, 유저가 Excel 파일을 열지 않은 사이에 실행해 두고 싶은 편집 작업에 적합하다.

PowerShell로 작성하는 단점



열린 책을 편집하는 데 적합하지 않습니다.



어디까지나 외부에서 Excel 파일을 편집하기 때문에, 유저가 북을 열고 있을 때에 매크로를 실행시키고 싶은 경우등은 적합하지 않다.

기본 쓰기



기본형 샘플

$excel = New-Object -ComObject Excel.Application
$book = $null
try {
    # VBAでいう「Application.Visible」などにあたる
    # このほか、Applicationオブジェクトから呼び出すメソッド等は$excelから呼び出すことができる
    $excel.Visible = $false
    $excel.DisplayAlerts = $false

    # ブックを開く(VBAと書き方がほぼおなじ
    $book = $excel.Workbooks.Open("C:\test\test.xlsx")

    # 1シート目を取得(インデックスは1から始まる)
    $sheet = $book.Sheets(1)

    $range = $sheet.Range("A1")

    # セルへの書き込み
    $range.Value = "bbbbb"

    # セルの値の取得
    # Valueの後ろにカッコが必要
    Write-Host $range.Value()

    [void]$book.Save()

} finally {
    if ($book -ne $null) {
        [void]$book.Close($false)
        [System.Runtime.Interopservices.Marshal]::ReleaseComObject($book)
    }

    # Excelの終了
    [void]$excel.Quit()

    # オブジェクトの開放
    # ApplicationとBookに対して行えばよい
    [System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)
}


이럴 때는 어떻게? 알고 싶을 때



VBA에서의 실현 방법을 조사하고 그것을 그대로 PowerShell의 구문으로 바꾸는 것만으로 대략 움직인다.

속성에 괄호가 필요할 수 있음



( 님 정보 제공 해 주셔서 감사합니다)

예를 들면, 상기 샘플의 값의 취득으로 $range.Value() 로 했듯이, 프로퍼티를 참조하는 경우에서도, 인수 있는 프로퍼티를 취득하는 경우는 뒤에 괄호가 필요. VBA에서는 생략할 수 있으므로 Value 프로퍼티에 인수가 있는 것을 잊어버리는 경향이 있지만, PowerShell로 괄호를 잊으면 의도하지 않은 결과가 돌아온다.

참조 : Range.Value 속성 (Excel) | Microsoft Docs

↓ 시도한 코드

괄호 유무 시험 샘플 발췌
Write-Host "括弧なし"
Write-Host $range.Value
Write-Host "括弧あり"
Write-Host $range.Value()

↓출력 결과
括弧なし
Variant Value (Variant) {get} {set} 
括弧あり
bbbbb

이에 대해, Width 프로퍼티 등 인수가 없는 프로퍼티은, 괄호 없이도 값을 취득할 수 있다 (괄호 있어도 취득을 할 수 있다).

Width 괄호 유무 시험 샘플 발췌
Write-Host "括弧なし"
Write-Host $range.Width
Write-Host "括弧あり"
Write-Host $range.Width()
括弧なし
52.8
括弧あり
52.8

VBA의 열거형을 사용하고 싶을 때



예를 들어 VBA에서 Range("A1").End(xlDown) 원하는 경우 xlDown는 어떻게해야합니까?

값을 확인하고 직접 사용



MS 레퍼런스(예: xldirection 열거(Excel) | Microsoft Docs )를 조사하거나 VBA의 이미디에이트 윈도우에서 Debug.Print 하거나 해 조사한 수치를 그대로 사용한다.

↓VBA의 이미디에이트 윈도우로 수치를 조사한 모습


숫자를 사용하는 샘플
$sheet.Range("A1").End(-4121)

어셈블리를 로드하고 열거형 사용



.NET 측에도 같은 열거형이 준비되어 있으므로, 그것을 로드해 사용한다.

어셈블리를 로드하는 샘플
# 最初に1度ロードすればよい
[void][Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Interop.Excel")

# 型名が長いのでいったん変数に入れる
$xlDirection = [Microsoft.Office.Interop.Excel.XlDirection]

# 列挙型を使う
[void]$range.End($xlDirection::xlDown).Select()


메소드의 인수를 생략하고 싶을 때



예를 들어, 시트를 복사 할 때 첫 번째 인수의 Before를 지정하지 않고 두 번째 인수의 After 만 지정하고 싶을 수 있습니다.
VBA에서는 Worksheets("Sheet1").Copy After:=Worksheets("Sheet3") 라고 쓰면 좋지만 PowerShell에서는 다음과 같이 한다.

시트 복사본 샘플
$sheet.Copy([System.Reflection.Missing]::Value, "Sheet3")
[System.Reflection.Missing]::Value 는 메소드의 인수가 생략되었음을 나타내는 값입니다.

콘솔에 의도하지 않은 '0' 등이 나올 때



메소드의 반환값이 표준 출력에 쓰여 있을 가능성이 있다. PowerShell은 메서드나 함수의 반환값을 변수에 저장하지 않는 경우 표준 출력으로 나오기도 한다.
이를 피하기 위해서는 메소드의 머리에 [void]를 붙이면 좋다.

void를 붙이는 견본
[void]$sheet.Range("B2").Select()

좋은 웹페이지 즐겨찾기