2
\$\begingroup\$

This just opens all drawing files in solidworks and saves as a *.pdf file. I just wanted to to get a second set of eyes on this before I let it go on the actual drawings database (i.e. all our files) and hopefully make sure it won't encounter any errors.

using SolidWorks.Interop.sldworks;
using SolidWorks.Interop.swconst;
using System.Runtime.InteropServices;
using System;
using System.IO;

namespace PDF.csproj
{
    public partial class SolidWorksMacro
    {


        public void Main()
        {
            string pdfPath;
            string Path = "C:\\Users\\SAFEROADS201\\Desktop\\01-VMS Trailer";
            string txtPath = Path + "\\UpdatedPDFs.txt";
            string Date = DateTime.Now.ToShortDateString();
            string[] drwPaths = System.IO.Directory.GetFiles(Path, "*.slddrw", SearchOption.AllDirectories);
            foreach (string s in drwPaths)
            {
                if (!s.Contains("~$"))
                {
                    ModelDoc2 swDoc = null;
                    int longstatus = 0;
                    int longwarnings = 0;
                    pdfPath = s;
                    pdfPath = pdfPath.Replace("Drawings", "PDFs").Replace("SLDDRW", "PDF");
                    (new FileInfo(pdfPath)).Directory.Create();
                    swDoc = ((ModelDoc2)(swApp.OpenDoc6(s, 3, 0, "", ref longstatus, ref longwarnings)));
                    longstatus = swDoc.SaveAs3(pdfPath, 0, 0);
                    swDoc = null;
                    swApp.CloseAllDocuments(true);
                }
            }
            System.IO.File.WriteAllText(txtPath, Date);
         }

        /// <summary>
        ///  The SldWorks swApp variable is pre-assigned for you.
        /// </summary>
        public SldWorks swApp;
    }
}
\$\endgroup\$
2
\$\begingroup\$

Naming

  • Also the naming guidlines doesn't explictly mention variable local to a method, you should name them using camelCase casing.

  • Naming methods, properties and variables in a meaningful way will help you or Mr.Maintainer to faster grasp what a variable/method/class is about.

  • Shortening of names like foreach (string s in drwPaths) should be avoided.

General

  • If the right side type of an assignment is obvious one should use var like

    var path = "C:\\Users\\SAFEROADS201\\Desktop\\01-VMS Trailer";  
    
  • By using guard conditions you can save horizontal spacing which improves readability of the code.

  • By extracting the algorithm to a method in a separate class you can reuse it.

  • Filepaths should be composed using the System.IO.Path.Combine() method.

  • If you are dealing with a large amount of files you should prefer Directory.EnumerateFiles() over Directory.GetFiles().
    From the documentation of GetFiles():

    The EnumerateFiles and GetFiles methods differ as follows: When you use EnumerateFiles, you can start enumerating the collection of names before the whole collection is returned; when you use GetFiles, you must wait for the whole array of names to be returned before you can access the array. Therefore, when you are working with many files and directories, EnumerateFiles can be more efficient.

  • variables should be declared as near as possible to their usage.

  • strings, especially strings which represents filepaths should be marked as verbatim string literal to ignore escape sequences. See this SO answer

Refactoring

Let us start by introducing a new class called SolidWorkFileConverter, add a constructor and add a method named ToPdf()

public class SolidWorkFileConverter
{
    private SldWorks swApplication;
    public SolidWorkFileConverter(SldWorks swApp)
    {
        swApplication = swApp;
    }

    public void ToPdf(string searchPath, string logFileName)
    {
        var logFileDestionation = System.IO.Path.Combine(searchPath, logFileName);
        var currentDate = DateTime.Now;
        var drawingFiles = System.IO.Directory.EnumerateFiles(Path, "*.slddrw", SearchOption.AllDirectories)  
                                              .Where(file => !file.Contains("~$"));
        foreach (var drawingFile in drawingFiles)
        {
            ToPdf(drawingFile);
        }
        WriteToLog(logFileDestination, currentDate);
    }

    public void ToPdf(string drawingFile)
    {
        string destinationFileName = ComposeDestinationFileName(drawingFile);
        CreateDestinationDirectory(destinationFileName); 
        int state = 0;
        int warningState = 0;
        ModelDoc2 swDoc = (ModelDoc2)(swApplication.OpenDoc6(s, 3, 0, "", ref state, ref warningState));
        state = swDoc.SaveAs3(pdfPath, 0, 0);
        swDoc = null;
        swApplication.CloseAllDocuments(true);
    }

    private string ComposeDestinationFileName(string sourceFileName)
    {
        return sourceFileName.Replace("Drawings", "PDFs").Replace("SLDDRW", "PDF");
    }

    private void CreateDestinationDirectory(string destinationFileName)
    {
        string directoryName = System.IO.Path.GetDirectoryName(destinationFileName);
        System.IO.Directory.CreateDirectory(directoryName);
    }

    private void WriteToLog(string logFileDestination, DateTime currentDate)
    {
        System.IO.File.WriteAllText(logFileDestination, currentDate.ToShortDateString());
    }
}

this can now be called by your main() method (or used anywhere) like

string searchPath = @"C:\Users\SAFEROADS201\Desktop\01-VMS Trailer";
string logFileName = System.IO.Path.Combine(searchPath , "UpdatedPDFs.txt");
SolidWorkFileConverter converter = new SolidWorkFileConverter(swApp);
converter.ToPdf(searchPath, logFileName);
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.