xlogI125’s blog

パソコン作業を効率化したい

Acrobat JavaScript練習 しおり(上位レベル以外)削除

下記の結合と分割を繰り返していると しおりの階層 が深くなるので、上位レベル以外の しおり を削除する。

  • ファイルを結合 → 常にPDFファイルにしおりを追加
  • ページを整理 → 分割 → 上位レベルのしおり → ファイル名にしおり名を使用
▽ 別紙1   ← 上位レベル
 ▽ 別紙1  ← 上位レベル以外
    別紙1 ← 上位レベル以外
▽ 別紙1A   ← 上位レベル
 ▽ 別紙1A  ← 上位レベル以外
    別紙1A ← 上位レベル以外
▽ 別紙2   ← 上位レベル
 ▽ 別紙2  ← 上位レベル以外
    別紙2 ← 上位レベル以外
▽ 別紙3   ← 上位レベル
 ▽ 別紙3  ← 上位レベル以外
    別紙3 ← 上位レベル以外
▽ 別紙5   ← 上位レベル
 ▽ 別紙5  ← 上位レベル以外
    別紙5 ← 上位レベル以外

↓

□ 別紙1
□ 別紙1A
□ 別紙2
□ 別紙3
□ 別紙5

使い捨てスクリプト

JavaScript

// Acrobat Standard DC (2022年9月頃), Windows 11
// JavaScript デバッガー の コンソール から実行

var str = (() => {
  // 上位レベル以外の しおり を削除
  const bkms = this.bookmarkRoot.children;
  if (bkms != null) {
    for (var i = 0; i < bkms.length; i++) {
      while (bkms[i].children != null) {
        bkms[i].children[0].remove();
      }
    }
  }
}).toString();

var src = "(" + str + ")();";

app.addSubMenu({
  cName: "MyBookmarkEdit", 
  cUser: "しおりを調整", 
  cParent: "Edit", 
  nPos: 0
});

app.addMenuItem({
  cName: "MyBookmarkRemove", 
  cUser: "上位レベル以外の しおり を削除", 
  cParent: "MyBookmarkEdit", 
  nPos: 0, 
  cExec: src, 
  cEnable: "event.rc = (event.target != null)", 
  cMarked: "event.rc = false", 
  bPrepend: false
});

IAC

  • Acrobatがバックグラウンドプロセスとして残るので練習以外で使用しない
' Excel 2019, Acrobat Standard DC (2022年9月頃), Windows 11
' 参照設定: Acrobat (Adobe Acrobat 10.0 Type Library)

' PDFをタブに表示させた状態でマクロを実行してください

Option Explicit

#Const DEBUG_ = False

Public Sub 上位レベル以外のしおりを削除()

#If DEBUG_ Then
  Dim avApp As Acrobat.AcroApp
  Dim avDoc As Acrobat.AcroAVDoc
  Dim pdDoc As Acrobat.AcroPDDoc
#Else
  Dim avApp As Object
  Dim avDoc As Object
  Dim pdDoc As Object
#End If

  Dim jso As Object
  Dim bkmR As Object
  Dim bkms() As Variant, bkmChildren() As Variant
  Dim i As Long, j As Long

  On Error GoTo ErrorHandler

  ' 「-2146959355 サーバーの実行に失敗しました」と表示される場合は
  ' タスクマネージャーで
  ' バックグラウンドプロセスとして残っているAcrobatを終了させる
  Set avApp = VBA.Interaction.CreateObject(Class:="AcroExch.App")

  Set avDoc = avApp.GetActiveDoc()
  Set pdDoc = avDoc.GetPDDoc()
  Set jso = pdDoc.GetJSObject()

  Set bkmR = CallByName(jso, "bookmarkRoot", VbGet)

  bkms = CallByName(bkmR, "children", VbGet)

  On Error GoTo ErrBkmNoChildren

  For i = 0 To UBound(bkms) Step 1
    bkmChildren = CallByName(bkms(i), "children", VbGet)

    For j = UBound(bkmChildren) To 0 Step -1
      CallByName bkmChildren(j), "remove", VbMethod
    Next j

    For j = 0 To UBound(bkmChildren) Step 1
      Set bkmChildren(j) = Nothing
    Next j

SkipBkmChildrenRemove:
  Next i

  For i = 0 To UBound(bkms) Step 1
    Set bkms(i) = Nothing
  Next i

ErrorHandler:
  Set bkmR = Nothing
  Set jso = Nothing
  Set pdDoc = Nothing
  Set avDoc = Nothing
  Set avApp = Nothing
  Debug.Print _
    VBA.Information.Err.Number, _
    VBA.Conversion.Error(VBA.Information.Err.Number)

  Exit Sub

ErrBkmNoChildren:
  Resume SkipBkmChildrenRemove

End Sub