• 締切済み

VBAでExcelファイルのPDF自動化

表題の通りの事をしたいと思っています。とあるサイトで参照したvbaコードで、デスクトップにファイルをExcelのブック名と同じ名前でPDFに変換するところまで出来ました。あと自動でやりたいことは2つあり、(1)とあるセルの情報を読み込み保存名にしたい【○○○.pdfという具合に】、(2)生成したpdfファイルの保存先をマクロ内に設け指定したいです。【\\サーバー名\○○\△△\□□などのように】 現状までのコードを表記します。わかる方いらっしゃいましたら、お手数ですがアドバイスお願いします。 自分はマクロは手を出したばかりで、初心者です。宜しくお願いします。 Sub pdf() Dim i As Integer Dim s_prn As String, oldprn As String, flg As Boolean On Error Resume Next s_prn = "Adobe PDF" 'インストールされているPDFプリンタの名前 oldprn = ActivePrinter 'アクティブプリンタを取得 If InStr(oldprn, s_prn) = 0 Then '切替えたいプリンタがアクティブプリンタでない場合 flg = False 'プリンタ切替フラグ For i = 0 To 99 ActivePrinter = s_prn & " on Ne" & Format(i, "00") & ":" '「"プリンタ名"on NeXX:」形式PC用 ActivePrinter = "Ne" & Format(i, "00") & ": の " & s_prn '「NeXX: の "プリンタ名"」形式PC用 If ActivePrinter <> oldprn Then flg = True 'プリンタ切替成功 Exit For End If Next i If flg = False Then 'プリンタ切替失敗の場合 MsgBox "プリンタ名:" & s_prn & " が見つかりません。" Exit Sub End If End If ActiveSheet.PrintOut ActivePrinter = oldprn 'アクティブプリンタを元に戻す MsgBox "終了しました。" End Sub

みんなの回答

  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.5

#2です。 プリンター名決め打ちで良ければもっと簡単な方法がある事が判明しました。 alternativePrinter = getPrinterPort("Microsoft Office Document Image Writer") のところは、お手元のPCにインストールされているプリンタを設定する必要があります。ダミーで使用するだけで、実際には印刷させません。 Sub MakePdf2() Dim sh As Worksheet Dim objAbDist As Object Dim strDefaultPrinter As String Dim printerList() As String Dim i As Long Dim acrobatPrinter As String, alternativePrinter As String Const destFolder As String = "E:\pdfTest" acrobatPrinter = getPrinterPort("Adobe PDF") alternativePrinter = getPrinterPort("Microsoft Office Document Image Writer") Set objAbDist = CreateObject("PdfDistiller.PdfDistiller.1") strDefaultPrinter = Application.ActivePrinter Set sh = ActiveSheet Application.ActivePrinter = alternativePrinter Application.ActivePrinter = acrobatPrinter Application.ScreenUpdating = False sh.PrintOut Copies:=1, preview:=False, _ printtofile:=True, Collate:=True, prtofilename:=GetDesktopPath & "\temp.ps" objAbDist.FileToPDF GetDesktopPath & "\temp.ps", destFolder & "\" & sh.Range("A1").Value & ".pdf", vbNullString If Dir(destFolder & "\" & sh.Range("A1").Value & ".pdf") <> "" Then Kill destFolder & "\" & sh.Range("A1").Value & ".log" Application.ActivePrinter = strDefaultPrinter Kill GetDesktopPath & "\temp.ps" Application.ScreenUpdating = True End Sub Function getPrinterPort(printerName As String) Dim WshShell As Object Dim regValue As String Dim buf As String Set WshShell = CreateObject("WScript.Shell") On Error Resume Next regValue = WshShell.regread("HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Devices\" & printerName) If IsNull(regValue) Then getPrinterPort = "" Exit Function End If On Error GoTo 0 buf = Replace(regValue, "winspool,", "") buf = printerName & " on " & buf getPrinterPort = buf Set WshShell = Nothing End Function Private Function GetDesktopPath() As String Dim wScriptHost As Object, strInitDir As String Set wScriptHost = CreateObject("Wscript.Shell") GetDesktopPath = wScriptHost.SpecialFolders("Desktop") Set wScriptHost = Nothing End Function

  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.4

#3の続きです。 1.Activesheetを、A1セルに入れた文字列をファイル名(pdfは勝手につける)にして、コード中で指定するフォルダーに出力します。コード中のフォルダーは、お手元の環境に合わせて変更が必要です。 2.前準備が必要です。 コントロールパネルのデバイスとプリンタから、 Acrobat PDFをWクリック、メニューのプリンタをクリック、プロパティを選択、 全般タブの基本設定ボタンをクリック、Adobe PDF設定タブの基本設定ボタンをクリック、Adobe PDF設定タブの 「システムのフォントのみ使用し、文書のフォントを使用しない」のチェックを外す必要があります(Acrobat9の場合) Acrobat6では、フォントを送信しないという表現でした。 これを行わないと、PostScriptファイル出力時にエラーとなります。 3.Excelはシート毎に印刷条件を保持していて、これが邪魔をする事があります。(コントロールパネルでの設定より優先されるらしい)これをクリアするため、面倒な事をしています。 4.あまり役に立たない情報(または言い訳) VirtualBOX環境で試験したところ、取得されるプリンターリストに余分な情報が含まれていて悩まされました。おかげでコードの推敲は不十分で時間切れです。本来は実行しているPCに出力してから、サーバーにコピーする方が良いでしょう。 以上、ご参考まで。

  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.3

#2です。文字数オーバーのため2分割します。 Private Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" _ (ByVal hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, _ ByVal samDesired As Long, phkResult As Long) As Long Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long Private Declare Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA" _ (ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, _ lpType As Long, lpData As Any, lpcbData As Long) As Long Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" _ (ByVal lpClassName As String, ByVal lpWindowName As String) As Long Private Const KEY_QUERY_VALUE = &H1 Private Const HKEY_CURRENT_USER = &H80000001 'Activesheetをpdf出力 Sub MakePdf() Dim sh As Worksheet Dim objAbDist As Object Dim strDefaultPrinter As String Dim printerList() As String Dim i As Long Dim acrobatPrinter As String, alternativePrinter As String Const destFolder As String = "E:\pdfTest" printerList = Get_Printers If UBound(printerList) = 0 Then Exit Sub For i = LBound(printerList) To UBound(printerList) If InStr(printerList(i), "Adobe PDF") > 0 Then acrobatPrinter = printerList(i) Else alternativePrinter = printerList(i) End If Next i Set objAbDist = CreateObject("PdfDistiller.PdfDistiller.1") strDefaultPrinter = Application.ActivePrinter Set sh = ActiveSheet 'ダミーのプリンタに一旦切り替えて、シート毎の印刷設定を一括クリア Application.ActivePrinter = alternativePrinter Application.ActivePrinter = acrobatPrinter Application.ScreenUpdating = False sh.PrintOut Copies:=1, preview:=False, _ printtofile:=True, Collate:=True, prtofilename:=GetDesktopPath & "\temp.ps" objAbDist.FileToPDF GetDesktopPath & "\temp.ps", destFolder & "\" & sh.Range("A1").Value & ".pdf", vbNullString If Dir(destFolder & "\" & sh.Range("A1").Value & ".pdf") <> "" Then Kill destFolder & "\" & sh.Range("A1").Value & ".log" Application.ActivePrinter = strDefaultPrinter Kill GetDesktopPath & "\temp.ps" Application.ScreenUpdating = True End Sub 'プリンターのリスト取得0スタートの文字列配列で戻す '参照:http://blogs.yahoo.co.jp/bardiel_of_may/40864687.html Private Function Get_Printers() As String() Dim objWSH As Object Dim objPrinter As Object Dim sPrinterList() As String Dim sTemp1 As String Dim sTemp2() As String Dim i As Long Dim ctr As Long Const SUB_ROOT = "Software\Microsoft\Windows NT\CurrentVersion\Devices" Set objWSH = CreateObject("WScript.Network") Set objPrinter = objWSH.EnumPrinterConnections If objPrinter.Count < 2 Then MsgBox "プリンタを取得できません", vbExclamation GoTo Exit_Proc Else ctr = 0 For i = 0 To objPrinter.Count - 1 Step 2 ReDim Preserve sPrinterList(ctr) sPrinterList(ctr) = objPrinter(i + 1) ctr = ctr + 1 Next End If ReDim Preserve sTemp2(0 To ctr - 1) For i = 0 To ctr - 1 sTemp1 = RegRead_API(HKEY_CURRENT_USER, SUB_ROOT, sPrinterList(i)) sTemp1 = Replace(sTemp1, "winspool,", "") sTemp2(i) = sPrinterList(i) & " on " & sTemp1 Next Get_Printers = sTemp2 Exit_Proc: Set objPrinter = Nothing Set objWSH = Nothing End Function 'レジストリを読む Private Function RegRead_API(lRoot As Long, sSubRoot As String, sEntryName As String) As String Dim lRet As Long Dim hWnd As Long Dim sVal As String ' hWnd = FindWindow("XLMAIN", Application.Caption) 'xl2000の時 hWnd = Application.hWnd lRet = RegOpenKeyEx(lRoot, sSubRoot, 0, KEY_QUERY_VALUE, hWnd) sVal = String(255, " ") lRet = RegQueryValueEx(hWnd, sEntryName, 0, 0, ByVal sVal, LenB(sVal)) RegCloseKey hWnd sVal = Left$(sVal, InStr(sVal, vbNullChar) - 1) RegRead_API = sVal End Function Private Function GetDesktopPath() As String Dim wScriptHost As Object, strInitDir As String Set wScriptHost = CreateObject("Wscript.Shell") GetDesktopPath = wScriptHost.SpecialFolders("Desktop") Set wScriptHost = Nothing End Functio

  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.2

xl2007以降なら、#1さんの例の様に話は簡単なのですが、xl2003以前で、Acrobatを用いて行おうとするとなかなか骨です。 下記リンクがお役に立つのではないかと思います。 http://okwave.jp/qa/q4847920.html http://okwave.jp/qa/q6205938.html リンク先に"プリンタ名"on NeXXの取得をレジストリから行う部分もありますが、お示しのコードは泥臭いけれど簡便で良いですね。 行っている事の解説はこちらにあります。今日検索していてたまたま辿り着きました。 http://helpx.adobe.com/jp/legacy/kb/511120.html ただ、 >デスクトップにファイルをExcelのブック名と同じ名前でPDFに変換するところまで出来ました。 で良いのなら、セルから読んだ名前に付け替えれば簡単かと思います。 保管場所も同様で、カレントディレクトリに出力されるのかどうか分かりませんが、目的の場所にコピーまたは移動してやればよろしいのではないでしょうか。 以上、ご参考まで。

cheesepizza
質問者

補足

自分が行おうとしているのは、excel 2003での作業になります。 教えていただきましたリンク内のコードをマクロに記憶させて実行してみましたが’400’というエラーが出てしまいできませんでした。 >セルから読んだ名前に付け替えれば簡単かと思います。 Dim Fname As String Fname = WorkSheet("Sheet1").Range("A1").value などとすればいいのでしょうか。 FnameをPDFでの保存名にするには、どうすればいいでしょうか。 >保管場所も同様で、カレントディレクトリに出力されるのかどうか分かりませんが、目的の場所にコピーまたは移動してやればよろしいのではないでしょうか。 現場のオペレーターの方の作業を極力減らしたいので、マクロを走らせただけで、所定のサーバー内にPDF形式でexcelシートを保存したいと考えております。 できれば具体的なコードを示していただけると助かります。 初心者ですいません。宜しくお願い致します。

  • shut0325
  • ベストアンサー率40% (490/1207)
回答No.1

単純にPDF形式で保存すればよいかと思います。 コードは FPath="\\サーバー名\○○\△△\□□\":'最後に¥をつけるのを忘れずに。 FName=ActiveSheet.Range("A1").Value:'仮にファイル名をアクティブシートのセルA1の値としています。 ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:=FPath & FName & ".pdf" こんな感じで。

関連するQ&A

  • EXECL VBAにて自動印刷100枚でフリーズ

    フィリーズの原因 とりあえず、アクティブプリンターのみで印刷を連続すると異常なし 交互に印刷すると今度はリソース不足が出ました。 最後に、EPSON LPプリンターのみに連続印刷でやはりリソース不足が出ました。 どうもアクティブプリンターからの切替でリソースを必要としているみたいですが 対策はをご教示下さい。 ======================================== Sub チェンジプリンター() '印刷切り替え Dim myPrinter As String myPrinter = Application.ActivePrinter '現在のプリンターを記憶 If Worksheets("DeviceRead-Write").Cells(6, 13).Value = 2 Then 'I6が2ならEPSON_2プリンターに印刷する Application.ActivePrinter = "EPSON_2 on Ne00:" 'プリンターを切り替える ActiveSheet.PrintOut 'シートFormの印刷 Application.ActivePrinter = myPrinter 'プリンターを元に戻す End If If Worksheets("DeviceRead-Write").Cells(6, 13).Value = 1 Then 'I6が1ならEPSON LPプリンターに印刷する ActiveSheet.PrintOut 'シートFormの印刷 End If End Sub ==========================================

  • エクセルVBAでPDFを1枚目のみ印刷したい

    下記のVBAに複数PDFが重なっている場合は、一枚目のみ印刷する文面を 挿入したいのですがうまくいきません Sub Test() Dim z As Object Dim i As Long Dim f, p As String Application.ScreenUpdating = False Set z = CreateObject("WScript.Shell") p = Application.ActivePrinter For i = 1 To Range("A1").End(xlDown).Row f = "h:\hozei\" & Cells(i, 1).Value & ".pdf" If Dir(f) <> "" Then z.Run ("AcroRd32.exe /t " & f) Else Cells(i, 2).Value = Cells(i, 1).Value Cells(i, 1).Value = "" End If Next i Set z = Nothing End Sub お忙しいところ申し訳ございません どなたかご教示願います。

  • Execl VBA UserForm1の印刷先

    Execl VBA UserForm1の印刷先を変更したいのですが Execl VBAで困っています。 UserFormの印刷を条件を変えてプリンター1とプリンター2に振り分けたいのですが ネットを検索してもいい方法が見つかりません。 UserFormはOSのプリンターを参照するため思うように印刷できません。 一度下記を試しましたが、試通常使うプリンターでしか印刷出来ません UserFormのプリンター切替方法のご伝授宜しくお願い致します。 =========================================== Sub チェンジプリンター() Dim myPrinter As String myPrinter = Application.ActivePrinter '現在のプリンターを記憶 If Worksheets("DeviceRead-Write").Cells(6, 11).Value = 2 Then 'I6が2ならEPSON_2プリンターに印刷する Application.ActivePrinter = "EPSON_2 on Ne02:" 'プリンターを切り替える Range("A4").Value = Application.ActivePrinter 'プリンターの確認 UserForm1.PrintForm 'フォームの印刷 Application.ActivePrinter = myPrinter 'プリンターを元に戻す Range("A2").Value = Application.ActivePrinter 'プリンターの確認 End If If Worksheets("DeviceRead-Write").Cells(6, 11).Value = 1 Then 'I6が2ならEPSON_1プリンターに印刷する Range("D2").Value = Application.ActivePrinter 'プリンターの確認 UserForm1.PrintForm 'フォームの印刷 End If End Sub

  • エクセルVBAのイベントで質問です。

    ダブルクリックイベントで、G12:G31の範囲の文字列をB10:B27の範囲(最下行)に入れていくものを使っていますが、新たにH12:H31にある文字列もダブルクリックするとC10:C27の範囲(最下行)に入れていけるようにしたいと思います。 どのようにすればいいでしょうか。 ご存知の方いらっしゃればお教えいただけると助かります。 Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Excel.Range, _ Cancel As Boolean) Dim i As Long Dim flg As Boolean If Intersect(Target, Range("G12:G31")) Is Nothing Then Exit Sub If IsEmpty(Target.Value) Then Exit Sub With Worksheets("シートA") For i = 10 To 27 If .Range("B" & i).Value = "" Then .Range("B" & i).Value = Target.Value flg = True Exit For End If Next i If flg = False Then MsgBox .Name & " がいっぱいです。" End If End With Cancel = True End Sub

  • ExcelのVBAソースコード(一部)の翻訳

    ソースコードの一部ですが、開発者が他界し訊けずにおります。 今後自分でもVBAを勉強しますが、お教えいただけますでしょうか。 なお冒頭は Function process_new(m0 As Integer, m As Integer, d As Variant, ans As Double) As Integer Dim a(501), b(501), s(501), r(501) As Double Dim w(501), g(11), xx As Double Dim s1 As Double Dim k(501) As Integer Dim i, j, flg As Integer でスタートしています。 =(以下、質問内容)==== s1 = s(k(0)) * 1.618 flg = 0 For i = m0 To m - 3 If Not i = k(0) Then If s1 > s(i) Then flg = flg + 1 End If End If Next i =(以上)====

  • VBAでスロットを作る

     VBAでゲームを作ろうとしています。まず、手始めに簡単なスロットを作っています。スロットを回転させて止めるまではできたのですがメッセージを出す段階でメッセージが2回、0とiの値が出ます。次のコードなのですが、なぜできないのか、どうすればできるようになるのか教えてください。よろしくお願いします。 Sub SlotLoop_1() Dim i As Long Static Flg As Boolean Flg = Not Flg 'ボタンを使えるようにする With [a1] 'A1を選ぶ Do If Flg = False Then Exit Do i = (i + 1) Mod 10 '(i+1)を10で割った余り。 .Value = i DoEvents Loop End With MsgBox i 'ここが問題 End Sub

  • VBAのDoEventsが上手く動きません

    お世話になります。 ExcelのVBAで印刷処理をしているのですが、印刷枚数が多いのでDoEventsイベントを入れ、印刷中断処理を行いたいのですが、上手くできません。 印刷中ダイアログが表示されるのが原因なのでしょうか?それともコードの書き方が悪いのでしょうか?よろしくお願いします。 コードは以下のとおりです。 ************************************************ Public Can_flg As Boolean ************************************************ Private Sub CommandButton1_Click()   Can_flg = True End Sub ************************************************ Private Sub UserForm_Activate()   Dim ms As String   Dim j As integer   Can_flg = False   For j = 1 To 31    DoEvents    If Can_flg = True Then      ms = MsgBox("印刷を中止します。", vbOKCancel)        If ms = vbOK Then         Exit For        Else         Can_flg = False        End If    End If    Me.Label1.Caption = "印刷中です… (" & j & "/" & i & "ページ)"    Sheets("テスト").PrintOut   Next j   Unload Me End Sub

  • vbaを使ってエクセルリストからPDFを印刷する

    エクセルシートA列に"ファイル場所+ファイル名.pdf"を合体させたリストを作成しました。 リストの上から順にPDFファイルを開き印刷するコードを作成しました。 印刷はされますが、リストの順番に印刷されず、ものすごくランダムに印刷されてしまいます。 このエラーについて、 「次々に実行させるから、ファイルの容量順に印刷されてしまうのでは? PDFを開いて、一旦閉じるコードを入れればよいのでは?」 というアドバイスをもらいましたが、どう対応したらよいか分かりません。 他に考えられる原因があるかもしれません。 教えて下さい。よろしくお願いします Dim i As Long 'セルC2に繰り返し数(ファイルの数)が入力されています For i = 1 To Range("C2").Value 'セルB**に印刷フラグを立て、「空欄」なら印刷、「1」なら印刷しないとしています '印刷フラグ「空欄」は印刷実行 If Cells(i + 1, 2).Value = "" Then PrinterName = Application.ActivePrinter fileName = Range("A" & i + 1).Value Set myShell = CreateObject("WScript.Shell") myShell.Run ("AcroRd32.exe /t " & fileName) '印刷フラグ「1」は印刷しない ElseIf Cells(i + 1, 2).Value = "1" Then End If Next i End Sub

  • Excel2010 VBA 条件色付け

    Sub sample() Dim r As Range For Each r In Range("q6:q30") If myIsNumeric(r) Then r.Offset(0, 1).Value = "数字" Else r.Offset(0, 1).Value = "文字" End If Next End Sub Function myIsNumeric(Target As Range) Dim r As Range Dim buf, tmp Dim flg As Boolean Dim i As Integer buf = Target For i = 1 To Len(buf) tmp = Mid(buf, i, 1) If IsNumeric(tmp) Then flg = True Exit For End If Next myIsNumeric = flg End Function を数字が入ってたら塗りつぶさないで、 数字が入ってなかったら塗りつぶすように直したいです。 あああ→塗る あああ1-1→塗らない 住所→塗る 住所12→塗らない

  • Excel VBAのコンボボックス

    お世話になります。 コンボボックス1と2と3は選択されますが コンボボックス4には何の表示もされません。 選択して条件設定は4つ以上できないのでしょうか? Dim ITE As Variant Dim flg As Variant Private Sub ComboBox3_Change() 'ComboBox4セット Dim ico As Long ico = 1 With ThisWorkbook.Worksheets("data") KEY = Me.ComboBox1.Text KEY2 = Me.ComboBox2.Text KEY3 = Me.ComboBox3.Text Me.ComboBox4.Clear Do While .Cells(ico, 1) <> "" If .Cells(ico, 1) = KEY And .Cells(ico, 2) = KEY2 And .Cells(ico, 3) = KEY3 Then ITE = .Cells(ico, 4).Value flg = 0 For I = 0 To Me.ComboBox4.ListCount - 1 If ITE = Me.ComboBox4.List(I) Then flg = 1 Next If flg = 0 Then Me.ComboBox4.AddItem ITE End If ico = ico + 1 Loop End With Me.ComboBox4.SetFocus End Sub

専門家に質問してみよう