.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

VB.Net - Print PDF

18 REPLIES 18
Reply
Message 1 of 19
HerveRob
5705 Views, 18 Replies

VB.Net - Print PDF

Dear All,

 

I can not figure out how to print my autocad drawings from a dedicated folder to pdf from a Visual Studio App.

So far, I can open a Autocad Drawing, upload the PC3 and PMP Files but can not figure out how to select a particular PaperSpace (called "A3 - ENGLISH").

 

Here below the code I have...I am pretty sure it can be simplify.

 

Imports System
Imports System.IO
Imports System.Text
Imports Autodesk.AutoCAD.Interop
Imports Autodesk.AutoCAD.Interop.Common
Imports System.Data.SqlClient
Imports System.Data.OleDb
Imports Microsoft.Office.Interop
Imports System.Runtime.InteropServices
Imports Excel = Microsoft.Office.Interop.Excel


Module Mdl_Print
    Dim AcadApp As AcadApplication
    Dim AcadDoc As AcadDocument

    Public Sub PDF_Print()

        Dim dirInfo As New DirectoryInfo(Frm_Main.LblFolder1.Text)
        Dim fileInfo As FileInfo



        Dim AcadApp As AcadApplication = New AcadApplication
        AcadApp.Visible = True
        AcadApp.WindowState = AcWindowState.acMax
        Dim success As Boolean = False


        For Each fileInfo In dirInfo.GetFiles("*.dwg") 'dwg for Autocad
            AcadDoc = AcadApp.Documents.Open(fileInfo.FullName)


            Dim oSS As AcadSelectionSet
            oSS = AcadApp.ActiveDocument.SelectionSets.Add("oSS")
            oSS.Clear()


            Try
                Dim ftype(0) As Int16
                Dim fdata(0) As Object
                ftype(0) = 410  'layout
                fdata(0) = "A3 - ENGLISH"

                oSS.Select(AcSelect.acSelectionSetAll, , , ftype, fdata)

                Dim objPrefFiles As AcadPreferencesFiles
                Dim PC3PathOld As String
                Dim PC3PathNew As String
                Dim PMPPathOld As String
                Dim PMPPathNew As String

                Dim PtConfigs As AcadPlotConfigurations
                Dim PlotConfig As AcadPlotConfiguration
                Dim PtObj As AcadPlot
                Dim BackPlot As Object

                'Set the preferences object
                objPrefFiles = AcadDoc.Application.Preferences.Files

                'Get the current Printer Config Path (pc3)
                PC3PathOld = objPrefFiles.PrinterConfigPath
                MessageBox.Show(PC3PathOld, "old Printer Config path (pc3)")
                objPrefFiles.PrinterConfigPath = "C:\Users\ROBERT\Documents\Deb + Herve + Will\B - Herve\Technip\Autocad\1st project\OpenExcel\PC3 Files"
                PC3PathNew = objPrefFiles.PrinterConfigPath
                MessageBox.Show(PC3PathNew, "new Printer Config path (pc3)")

                'Get the current Printer Desc Path (pmp)
                PMPPathOld = objPrefFiles.PrinterDescPath
                MessageBox.Show(PMPPathOld, "Printer Desc Path (pmp)")
                objPrefFiles.PrinterDescPath = "C:\Users\ROBERT\Documents\Deb + Herve + Will\B - Herve\Technip\Autocad\1st project\OpenExcel\PMP Files"
                PMPPathNew = objPrefFiles.PrinterDescPath
                MessageBox.Show(PMPPathNew, "Printer Desc Path (pmp)")



                PtObj = AcadDoc.Plot
                AcadApp.ActiveDocument.AcPlotType.acExtents()

                PtConfigs = AcadDoc.PlotConfigurations
                ''Add a new plot configuration
                PtConfigs.Add("PDF", False)
                '
                ''The plot config you created become active
                PlotConfig = PtConfigs.Item("PDF")
                
                ''Use this method to set the scale
                PlotConfig.StandardScale = AcPlotScale.acScaleToFit
                ''Updates the plot
                PlotConfig.RefreshPlotDeviceInfo()

                'Here you specify the pc3 file you want to use
                PlotConfig.ConfigName = "Herve.pc3"

                'You can select the plot style table here
                PlotConfig.StyleSheet = "monochrome.ctb"

                'You can select the Scale Line Weight
                PlotConfig.ScaleLineweights = True

                'Specifies Paper Size
                PlotConfig.CanonicalMediaName = "ISO_A3_(420.00_x_297.00_MM)"

                'Specifies whether or not to plot using the plot styles
                PlotConfig.PlotWithPlotStyles = True

                BackPlot = AcadDoc.GetVariable("BACKGROUNDPLOT")
                AcadDoc.SetVariable("BACKGROUNDPLOT", 0)

                'Updates the plot
                PlotConfig.RefreshPlotDeviceInfo()
                MessageBox.Show("scale" & PlotConfig.StandardScale)
                MessageBox.Show("canonical media name" & PlotConfig.CanonicalMediaName)
                MessageBox.Show("config name" & PlotConfig.ConfigName)
                MessageBox.Show("plot type" & PlotConfig.PlotType)
                MessageBox.Show("scale line weight" & PlotConfig.ScaleLineweights)

                'Now you can use the PlotTofile method
                If PtObj.PlotToFile(Replace(AcadDoc.FullName, "dwg", "pdf"), PlotConfig.ConfigName) Then
                    AcadDoc.Utility.Prompt(vbLf + "PDF Was Created")
                Else
                    AcadDoc.Utility.Prompt(vbLf + "PDF Creation Unsuccessful")
                End If

                'If you wish you can delete the plot configuration you created programmatically, and set the 'BACKGROUNDPLOT' system variable to its original status.
                PtConfigs.Item("PDF").Delete()
                PlotConfig = Nothing
                AcadDoc.SetVariable("BACKGROUNDPLOT", BackPlot)

                objPrefFiles.PrinterConfigPath = "C:\Users\ROBERT\AppData\Roaming\Autodesk\AutoCAD 2014\R19.1\enu\Plotters"
                objPrefFiles.PrinterDescPath = "C:\Users\ROBERT\AppData\Roaming\Autodesk\AutoCAD 2014\R19.1\enu\Plotters\PMP File

                oSS.Clear()

                If AcadDoc.Saved Then
                    AcadDoc.Close(False)
                End If
                AcadDoc = Nothing
                AcadApp.Quit()

                AcadApp = Nothing
                success = True
            Catch ex As Exception
                MsgBox(ex.Message + vbLf + ex.StackTrace)
                success = False
            End Try
            '            AcadDoc.Close()
            AcadDoc = Nothing
            '            AcadApp.Quit()
        Next
        AcadApp.Quit()
    End Sub


 Thank you

Herve

18 REPLIES 18
Message 2 of 19
SENL1362
in reply to: HerveRob

Did you find a solution?
Message 3 of 19
HerveRob
in reply to: HerveRob

Hello.
Unfortunatly, not yet.
Message 4 of 19
fieldguy
in reply to: HerveRob

Are you looking to change a to a particular layout?  If yes, go here - http://docs.autodesk.com/ACD/2014/ENU/index.html?url=files/GUID-5FA86EF3-DEFD-4256-BB1C-56DAC32BD868...

Message 5 of 19
SENL1362
in reply to: HerveRob

And what is the problem?
?Activate the layout="A3-English"?

in c#:
usingAutodesk.AutoCAD.PlottingServices;
...
LayoutManager lm = LayoutManager.Current;
lm.CurrentLayout = "A3-Englisch";

Message 6 of 19
HerveRob
in reply to: fieldguy

Well, basically, by default, my Autocad file opens on the layout "Model".

I have 3 other Layouts ("A3 - ENGLISH", "A3 - RUSSIAN" and "A3 - GERMAN").

 

What I am trying to do is to print only the layout "A3 - ENGLISH", for that, I create an AcadSelectionSet

First, I am trying to activate / select the layout "A3 - ENGLISH"

 

            Dim oSS As AcadSelectionSet
            oSS = AcadApp.ActiveDocument.SelectionSets.Add("oSS")
            oSS.Clear()

                Dim ftype(0) As Int16
                Dim fdata(0) As Object
                ftype(0) = 410  'layout
                fdata(0) = "A3 - ENGLISH"
                oSS.Select(AcSelect.acSelectionSetAll, , , ftype, fdata)
                AcadApp.ZoomExtents()
               

But it seems it doesnt do anything. The ZoomExtents() is performed in the layout "Model"

 

I might be wrong by using a AcadSelectionSet too...

 

PS: My application is a Windows Form, not an Autocad Wizard Template.

When I declare in VS the

Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.Geometry

it returns an error.

Message 7 of 19
SENL1362
in reply to: HerveRob

ok, i'll think you need a few extra miles.
Which AutoCAD version?

Step 1: The Import errors. Did you add the AutoCAD xxx references: acdbmgd, acmgd, AcCoreMgd.dll?
And set the property COPY LOCAL=FALSE for those references.

 

Step 2: Add Import Plot Services

Imports Autodesk.AutoCAD.PlottingServices



Step 3 Start Activate Layout:
(I am not used to VB.NET so my VB suggestions might not always be correct):
Dim lm as LayoutManager= LayoutManager.Current
lm.CurrentLayout = "A3-Englisch"

Try these 3 steps and see if you get a way from the start line :).



Message 8 of 19
HerveRob
in reply to: SENL1362

Hello,

 

I loaded the three dll but when I run the Marco (called from a button on the Main_Form) I get the follwing:

 

Could not load file or assembly 'Acdbmgd, Version=19.1.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. An attempt was made to load a program with an incorrect format

 

I am with Autocad 2014

Message 9 of 19
HerveRob
in reply to: SENL1362

...and also, when I compile le project, I am getting the following warnings:

 

Warning    1    Possible problem detected while building assembly 'OpenExcel': Referenced assembly 'accoremgd.dll' targets a different processor    OpenExcel

Warning    2    Possible problem detected while building assembly 'OpenExcel': Referenced assembly 'Acdbmgd.dll' targets a different processor    OpenExcel

Warning    3    The referenced assembly "acmgd" could not be resolved because it has a dependency on "System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" which is not in the currently targeted framework ".NETFramework,Version=v4.0,Profile=Client". Please remove references to assemblies not in the targeted framework or consider retargeting your project.    OpenExcel

 

 

Message 10 of 19
SENL1362
in reply to: HerveRob

I don't have Acad 2014/Visual Studio available today, but there are a few VS settings to be considered:
Application/Target Framework: probably 4.5
CPU type: ..
I can give you more details tomorrow if you tell me:
1.Computer type, i.e. W7, 64bits
2. What VS version





Message 11 of 19
HerveRob
in reply to: SENL1362

Hello,

If it can help, I am on Windows 7, 64Bits with VS 2010

Message 12 of 19
SENL1362
in reply to: HerveRob

This is how my Windows 7, 64bits, AutoCAD 2014, Visual Studio 2012 projects look like.

Notice the Copy Local =False for all three AC* references.

 

I would advise you to start with an empty VS project, without  Excel, and then try to get a Plot To PDF sample running.

Then add the the necessary  other functions.

AcadRefs.png

Message 13 of 19
HerveRob
in reply to: SENL1362

 

 

 

 

 

 

 

 

 

 

Hello,

 

I did the same but without success.

I read on a forum the acmgd.dll and acdbmgd.dll can only be use to made dll and can not be used in a stand-alone .EXE

 

Is that correct?

Message 14 of 19
SENL1362
in reply to: HerveRob

Possible, i don't have any experience with standalone exe's in c#. Correction, you are absolutely right, see this article:
http://spiderinnet1.typepad.com/blog/2012/05/add-circles-to-autocad-using-com-interop-and-c-in-stand...

I'll always use program's loaded in AutoCAD. And when needed start AutoCAD with these loaded programs with the necessary parameters and let them (Black box) handle the processing.
Message 15 of 19
HerveRob
in reply to: SENL1362

To be more detailled,

 

The Aplication I am doing is, a Windows Form under VS2010, that allows me to generate a document called 'Electrical Wiring Diagrams'.

Basically, on an excel spreadsheeet, I have information related to Electrical Consumers (tag, cable type, ID, size...).

The Application creates one Autocad Drawing per consumer and update the Block Attributes (text from the excel spreadsheet).

If the drawing already exist, the Application update the attributes only.

The Block is only made of text attributes only.

So far, I can generate the drawings, export the Attributes from Excel to the Autocad Drawings and vis-et-versa.

 

The remaining tasks I want to implement in my Application are:

   Print the drawings in PDF.

   Cloud all the Attributes that have changed between two revisions.

 

I am pretty sure the Print can be performed by the Interop so I will keep looking.

If I found, I will post the reply here.

 

Thanks you

Message 16 of 19
HerveRob
in reply to: HerveRob

Hello again,

 

So I solved the printing issue by using a solution proposed by Kean Walmsley (http://through-the-interface.typepad.com/through_the_interface/2007/09/driving-a-basic.html); creating a dll.

 

Now, I have a other issue !

In the proposed code (in the dll) the PlotConfigurationName are declared as values (fixed) while, I would like these to be bound to my application...

 

To be more clear, in my VS Application, I have a form that let the user select the paper format (A0 to A4) and the Plot Style (acad.ctb, monochrome.ctb or Grayscale.ctb). So the question is how to link the choices made by the user to that dll ?

 

Thank you.

 

For info, here below the code for printing:

Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.PlottingServices
Imports System.Runtime.InteropServices
Imports Autodesk.AutoCAD.Interop

Namespace PlottingApplication

    Public Class PlottingCommands

        <CommandMethod("simplot")> _
        Public Shared Sub SimplePlot()

            Dim doc As Document = Application.DocumentManager.MdiActiveDocument
            Dim ed As Editor = doc.Editor
            Dim db As Database = doc.Database
            Dim tr As Transaction = db.TransactionManager.StartTransaction()
            Using tr

                LayoutManager.Current.CurrentLayout = "A3 - ENGLISH"

                ' We'll be plotting the current layout
                Dim btr As BlockTableRecord = DirectCast(tr.GetObject(db.CurrentSpaceId, OpenMode.ForRead), BlockTableRecord)
                Dim lo As Layout = DirectCast(tr.GetObject(btr.LayoutId, OpenMode.ForRead), Layout)

                ' We need a PlotInfo object linked to the layout
                Dim pi As New PlotInfo()
                pi.Layout = btr.LayoutId

                ' We need a PlotSettings object based on the layout settings which we then customize


                ' Change the BACKGROUNDPLOT to 0
                Dim bgPlot As Short = CShort(Application.GetSystemVariable("BACKGROUNDPLOT"))
                Application.SetSystemVariable("BACKGROUNDPLOT", 0)

                Dim ps As New PlotSettings(lo.ModelType)
                ps.CopyFrom(lo)

                ' The PlotSettingsValidator helps create a valid PlotSettings object
                Dim psv As PlotSettingsValidator = PlotSettingsValidator.Current

                ' We'll plot the extents, centered and scaled to fit
                psv.SetPlotType(ps, Autodesk.AutoCAD.DatabaseServices.PlotType.Extents)
                psv.SetUseStandardScale(ps, True)
                psv.SetStdScaleType(ps, StdScaleType.ScaleToFit)
                psv.SetPlotCentered(ps, True)

                ' We'll use the standard DWG to PDF.pc3 and ANSI A Paper size
                psv.SetPlotConfigurationName(ps, "DWG to PDF.pc3", "ANSI_A_(11.00_x_8.50_Inches)")
                
                ' We need to link the PlotInfo to the PlotSettings and then validate it
                pi.OverrideSettings = ps
                Dim piv As New PlotInfoValidator()
                piv.MediaMatchingPolicy = MatchingPolicy.MatchEnabled
                piv.Validate(pi)

                ' A PlotEngine does the actual plotting (can also create one for Preview)
                If PlotFactory.ProcessPlotState = ProcessPlotState.NotPlotting Then
                    Dim pe As PlotEngine = PlotFactory.CreatePublishEngine()
                    Using pe

                        'Create a Progress Dialog to provide info and allow the user to cancel
                        Dim ppd As New PlotProgressDialog(False, 1, True)
                        Using ppd
                            ppd.PlotMsgString(PlotMessageIndex.DialogTitle) = "Custom Plot Progress"
                            ppd.PlotMsgString(PlotMessageIndex.CancelJobButtonMessage) = "Cancel Job"
                            ppd.PlotMsgString(PlotMessageIndex.CancelSheetButtonMessage) = "Cancel Sheet"
                            ppd.PlotMsgString(PlotMessageIndex.SheetSetProgressCaption) = "Sheet Set Progress"
                            ppd.PlotMsgString(PlotMessageIndex.SheetProgressCaption) = "Sheet Progress"
                            ppd.LowerPlotProgressRange = 0
                            ppd.UpperPlotProgressRange = 100
                            ppd.PlotProgressPos = 0

                            ' Let's start the plot, at last
                            ppd.OnBeginPlot()
                            ppd.IsVisible = True
                            pe.BeginPlot(ppd, Nothing)

                            ' We'll be plotting a single document
                            ' Let's plot to file

                            Dim toto As String
                            toto = Mid(doc.Name, InStrRev(doc.Name, "\") + 1, 256)
                            pe.BeginDocument(pi, doc.Name, Nothing, 1, True, "c:\plot\" & Mid(toto, 1, Len(toto) - 3) & "pdf")

                            ' Which contains a single sheet
                            ppd.OnBeginSheet()
                            ppd.LowerSheetProgressRange = 0
                            ppd.UpperSheetProgressRange = 100
                            ppd.SheetProgressPos = 0
        Dim ppi As New PlotPageInfo()

                            pe.BeginPage(ppi, pi, True, Nothing)
                            pe.BeginGenerateGraphics(Nothing)
                            pe.EndGenerateGraphics(Nothing)
        '' Finish the sheet
                            pe.EndPage(Nothing)
                            ppd.SheetProgressPos = 100
                            ppd.OnEndSheet()
        '' Finish the document
                            pe.EndDocument(Nothing)
        '' And finish the plot
                            ppd.PlotProgressPos = 100
                            ppd.OnEndPlot()
                            pe.EndPlot(Nothing)
                        End Using
                    End Using
                Else
                    ed.WriteMessage(vbLf & "Another plot is in progress.")
                End If

        ' Change the BACKGROUNDPLOT to original value
                Application.SetSystemVariable("BACKGROUNDPLOT", bgPlot)
            End Using
        End Sub
    End Class

End Namespace

 

Message 17 of 19
SENL1362
in reply to: HerveRob

You want to transfer parameters from you're Exe to AutoCAD?

C:\Program Files\...\acad.exe    /nologo    /p "AcadProfile"    /PlotPaper="A1"    /PlotStyle="acad.ctb"

 

 

        [CommandMethod("CLA")]
        public void GetCommandLineArguments()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            ed.WriteMessage("\nGetCommandLineArguments");

            foreach (string arg in Environment.GetCommandLineArgs())
                ed.WriteMessage("\n{0}",arg);

        }

Command: CLA

GetCommandLineArguments
C:\Program Files\Autodesk\Autodesk AutoCAD Map 3D 2014\acad.exe
/nologo
/p
AcadProfile
/PlotPaper=A1
/PlotStyle=acad.ctb
Command:

 

 

Message 18 of 19
HerveRob
in reply to: SENL1362

Hello,

I am not sure to understand your code, where to place it and you to run it. In my VS.exe? in a new dll class ?

 

I understand is it not possible to load the acdbmgd, acmgd and AcCoreMgd.dll in a VS Windows Form, this is the reason I made the DLL for printing.

 

In my VS Windows Form, I have a Button that the result shall print all files in a folder to pdf format.

So far I manage to do the loop for each file to open them and print them but i do not now how to change the paper format and style in that dll since it is already declared in the dll.

 

I do not know if I am clear so I will try with a ewample;

In the DLL I have declare the paper format as "ANSI_A_(11.00_x_8.50_Inches)". So all prints will be in that format.

In my VS Windows Form, I have a form that let the user select the paper format but since it is declare in the DLL, it is not working at all.

 

Sorry for being such ignorant on the subject.

Message 19 of 19
SENL1362
in reply to: HerveRob

I'm not sure what you don't understand so let me try to explain it as simple as possible.

If i understood you correctly you have two programs:

1. Your "Forms" program as a standalone exe program collecting AutoCAD filenames and Excel data;

2. AutoCAD and a loaded DLL creating the PDF plot.

 

What you want is to tranfer values from your Forms.exe to your AutoCAD Plot program.

Start with youre AutoCAD program collecting values from it's commandline.

(Youre DLL should be automatically loaded using Autoload or loaded by  AcadDoc.LSP, see sample below)

- Start a Windows Command Prompt(DOS CMD)

- Run AutoCAD:
C:\Program Files\...\acad.exe    /nologo    /p "AcadPlotProfile"    /PlotPaper="A1"    /PlotStyle="acad.ctb"

 

 

From: http://www.theswamp.org/index.php?topic=33538.0, thanks mohnston

AcadDoc.lsp  //must be somewhere in your AcadSearchPath folder
(defun c:PdfPlot()
   (SETVAR "CMDECHO" 0)
   (command "netload" "C:/Program Files/AutoCAD 2010/PlotNET2010.dll" "PdfPlot")
   (SETVAR "CMDECHO" 1)
   (princ)
)

 

[CommandMethod("PdfPlot")]
        public void PdfPlot()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            ed.WriteMessage("\nGetCommandLineArguments");

            foreach (string arg in Environment.GetCommandLineArgs())
                ed.WriteMessage("\n{0}",arg);

            string plotPaper=arg[xx];
            string plotStyle=arg[xx];

           SimplePlot( plotPaper, plotStyle, ...);
        }

 This would start AutoCAD with you're variables.

 

Next you need Forms.exe to start AutoCAD with these parameters:

ProcessStartInfo acadPdfPlot = new ProcessStartInfo();        
acadPdfPlot.FileName = @"C:\Program Files\...\acad.exe";
acadPdfPlot.Arguments = @"/nologo    /p \"AcadProfile\"    /PlotPaper=\"A1\"    /PlotStyle=\"acad.ctb\"";
Process.Start(acadPdfPlot);

 

I hope these steps may help you to get on track.

Note: this is just a simple example there other more advanded ways to do this.

 

 

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost