17 Replies Latest reply on May 11, 2018 6:52 PM by Cuinn Herrick

    Changing sheet format with macro causes duplicate blocks when multiple sheets exist in drawing.

    Lucas Malina

      Hi,

       

      I have seen this question asked once or twice a number of years ago but none of the previous threads I found were resolved as far as I could find and I thought there might be a new solution available.  Apologies in advance if this issue has already been solved.  I also searched the API documentation for a long time and couldn't find anything in there either.

       

      When we change the sheet format manually (because we use blocks in the sheet format) on multiple sheet drawings Solidworks prompts the user if they want to rename the duplicate block or use the existing definition.  The user then can easily select 'No' do not rename and we have no problems.

       

      Below is a screen shot of the prompt I am referring to.

       

      Untitled.jpg

       

      I then have a macro I am trying to use to batch change sheet formats using the SetupSheet6 command.

       

      The problem I am facing is when I run the macro, Solidworks doesn't get the chance to prompt the user and so it automatically uses the default option to rename the block and so I end up with multiple definitions of the same block instead of multiple instances of the single block definition.  This causes issues with our other macros which pull and push attributes to the blocks as it searches through and edits the block instances based on the block definition name.

       

      For example.  the block is called Title_Block and all macros can search and find the instance on the current sheet and modify the attributes but it doesn't work when on the second sheet the block is renamed to Title_Block_1 etc.

       

      My question is:

      Can I set the default option to "use existing block" for all duplicate blocks (using API or other method i.e. setting).  Or can I pause the macro while changing the sheet format to allow Solidworks to prompt the user and we can manually choose to use existing block instead of renaming?

       

      I am coding in VBA and using Solidworks 2017 on a windows 7 system.

       

      Thanks for your help.

      Lucas

        • Re: Changing sheet format with macro causes duplicate blocks when multiple sheets exist in drawing.
          Lucas Malina

          Has anyone got any ideas? Or can tell me it isnt possible?

           

          Thanks again.

            • Re: Changing sheet format with macro causes duplicate blocks when multiple sheets exist in drawing.
              Lucas Malina

              Hi Deepak,

               

              Thanks for commenting.  I don't have high hopes if you havent found anything.  Have you got any other ideas which might keep the processing times down?

               

              We often have drawing files with up to 40 sheets and searching through for 40 possible duplicate block names as suggested by Elmar seems it might take a long time to process.

                • Re: Changing sheet format with macro causes duplicate blocks when multiple sheets exist in drawing.
                  Elmar Klammer

                  Hi Lucas,

                   

                  Search your block instances is quick. They sit in the Blocks folder. I would see if I could relink any duplicate block instance to the first one and then delete all unused blocks.

                   

                  Elmar

                    • Re: Changing sheet format with macro causes duplicate blocks when multiple sheets exist in drawing.
                      Lucas Malina

                      Hi Elmar,

                       

                      Could you point me to some documentation for relinking duplicate block instances?

                        • Re: Changing sheet format with macro causes duplicate blocks when multiple sheets exist in drawing.
                          Elmar Klammer

                          API help is a good start

                           

                          Take a look at this example: #CODE|Make Sketch Block Instance Independent

                           

                          '--------------------------------
                          '
                          ' Preconditions: Part, assembly, or drawing document containing
                          '                one or more block definitions
                          '                and block instances is open.
                          '
                          ' Postconditions: The angles of all block instances are modified.
                          '
                          '---------------------------------
                          Option Explicit

                          Dim swApp As SldWorks.SldWorks
                          Dim swModel As SldWorks.ModelDoc2
                          Dim skMgr As SldWorks.SketchManager
                          Dim pBlock As SldWorks.SketchBlockDefinition
                          Dim pInst As SldWorks.SketchBlockInstance
                          Dim leaderPt As SldWorks.MathPoint
                          Dim insPt As SldWorks.MathPoint
                          Dim vInstPt As Variant
                          Dim vInstances As Variant
                          Dim vBlocks As Variant
                          Dim nInstanceCount As Long
                          Dim itr As Long
                          Dim jtr As Long
                          Dim bLinkToFile As Boolean
                          Dim strInsPoint As String

                          Sub main()

                              Set swApp = Application.SldWorks
                              Set swModel = swApp.ActiveDoc
                              Set skMgr = swModel.SketchManager

                              ' To change the angles, you must edit the block's sketches
                              swModel.EditSketch
                                 
                              vBlocks = skMgr.GetSketchBlockDefinitions
                             
                              ' Exit if no blocks
                              If IsEmpty(vBlocks) Then
                                  Exit Sub
                              End If
                             
                              ' Process block definitions
                              For itr = 0 To UBound(vBlocks)
                                         
                                  Set pBlock = vBlocks(itr)
                                 
                                  ' Block defintion linked to file?
                                  Debug.Print "  Link To File = " & pBlock.LinkToFile
                                 
                                  ' Block linked file name
                                  Debug.Print "  Link File Name = " & pBlock.FileName

                                  ' Block definition insertion point
                                  Set insPt = pBlock.InsertionPoint
                                  vInstPt = insPt.ArrayData
                                  strInsPoint = "  Insertion point: x = " + CStr(vInstPt(0) * 1000) + " , y = " + CStr(vInstPt(1) * 1000) + " , z = " + CStr(vInstPt(2) * 1000)
                                  Debug.Print strInsPoint
                                 
                                  ' Number of block instances of this block definition
                                  nInstanceCount = pBlock.GetInstanceCount
                                  Debug.Print "  Instance Count = " & nInstanceCount
                                 
                                  ' Process block instances
                                  If nInstanceCount > 0 Then
                                      vInstances = pBlock.GetInstances
                                      For jtr = 0 To UBound(vInstances)
                                          Set pInst = vInstances(jtr)

                                          ' Block instance position
                                          Set insPt = pInst.InstancePosition
                                          vInstPt = insPt.ArrayData
                                          strInsPoint = "        Instance position: x = " + CStr(vInstPt(0) * 1000) + " , y = " + CStr(vInstPt(1) * 1000) + " , z = " + CStr(vInstPt(2) * 1000)
                                          Debug.Print strInsPoint
                                         
                                          ' Get block instance angle
                                          Debug.Print "        Original angle = " & pInst.Angle
                                          ' Change block instance angle
                                          pInst.Angle = 90 / 57.3
                                          Debug.Print "        Modified angle = " & pInst.Angle
                                         
                                          ' Block instance scale
                                          Debug.Print "        Scale = " & pInst.Scale
                                         
                                          ' Block instance owner's sketch name
                                          Debug.Print "        Owner Sketch = " & pInst.GetSketch.Name
                                         
                                      Next jtr
                                  End If
                                               
                              Next itr
                             
                          End Sub

                            • Re: Changing sheet format with macro causes duplicate blocks when multiple sheets exist in drawing.
                              Lucas Malina

                              Much appreciated I'll see what I can piece together and report back if I have any success.

                                • Re: Changing sheet format with macro causes duplicate blocks when multiple sheets exist in drawing.
                                  Lucas Malina

                                  I am still struggling with this.  I have researched the links and api help and your example but still I cannot get this working.  I tried to rename the instance but it maintains the definition and I cannot find any way to move an instance or rename a definition.

                                   

                                  Can you provide more direction? I have tried and tried for days but still cant get around this problem.

                                   

                                  Thanks in advance.

                                  Lucas

                                    • Re: Changing sheet format with macro causes duplicate blocks when multiple sheets exist in drawing.
                                      Alex Burnett

                                      I have been having this problem too. I was inspired to sit down and sort it out though after seeing some of the code already posted. I know mine is in C# but it can be relatively easily translated if you're using VBA.

                                       

                                      I don't know why it's indented so far but there it is. The general idea is to find blocks that have a feature name that doesn't match the block definition file at its save location and then pointing them back to the feature that has the correct name (without the underscore).

                                       

                                      private void ConsolodateSketchBlockInstances(Model model)
                                      {
                                          var drawing = model.AsDrawing();
                                          var sketchManager = model.SketchManager;
                                          Dictionary<string, SketchBlockDefinition> SketchBlockOriginalNames = new Dictionary<string, SketchBlockDefinition>();
                                          List<SketchBlockDefinition> badblocks = new List<SketchBlockDefinition>(); 
                                          SketchBlockDefinition[] blockDefs = sketchManager.GetSketchBlockDefinitions();
                                          if (blockDefs != null && blockDefs.Length > 0)
                                          {
                                              foreach (SketchBlockDefinition blockDef in blockDefs)
                                              {
                                                  string[] fileNameSplit = blockDef.FileName.ToUpper().Split(new string[] { @"\", ".SLDBLK" }, StringSplitOptions.RemoveEmptyEntries);
                                      
                                      
                                                  string name = fileNameSplit[fileNameSplit.Length - 1]; // This is the name of the block file that is referenced
                                                  string blockDefName = blockDef.GetFeature().Name;
                                                  if (blockDefName.Equals(name) && !SketchBlockOriginalNames.ContainsKey(name))
                                                  {
                                                      SketchBlockOriginalNames.Add(name, blockDef);
                                                  }
                                                  else
                                                  {
                                                      badblocks.Add(blockDef);
                                                  }
                                              }
                                      
                                      
                                              foreach (SketchBlockDefinition blockDef in badblocks)
                                              {
                                                  string[] fileNameSplit = blockDef.FileName.ToUpper().Split(new string[] { @"\", ".SLDBLK" }, StringSplitOptions.RemoveEmptyEntries);
                                                          
                                                  string name = fileNameSplit[fileNameSplit.Length - 1]; // This is the name of the block file that is referenced
                                                  string blockDefName = blockDef.GetFeature().Name;
                                      
                                      
                                                  SketchBlockInstance[] instances = blockDef.GetInstances();
                                                  SketchBlockInstance thisinstance = null;
                                      
                                      
                                                  if (instances != null && instances.Count() > 0)
                                                  {
                                                      foreach (SketchBlockInstance inst in instances)
                                                      {
                                                          thisinstance = inst;
                                      
                                      
                                                          if (SketchBlockOriginalNames.ContainsKey(name))
                                                          {
                                                              thisinstance.Definition = (SketchBlockDefinition)SketchBlockOriginalNames[name];
                                                          }
                                                      }
                                                  }
                                              }
                                          }
                                          Trace.WriteLine("Done remove old drawing blocks");
                                      }
                                      

                                       

                                       

                                      Edit: Now that I have had lunch, I can clarify this. I iterated through all of the drawing blocks and saved the ones to a dictionary object where the feature tree item (in the blocks folder) have the same name as the saved .SLDBLK file. Everything else, I saved to a list called badblocks. Once I had both lists, I iterated through all of the bad block definitions and then got each instance of each bad definition and changed the definition to the correct one that I saved in the dictionary object. Once all of the definitions are corrected, the items with underscore numbers (..._1, ..._2, etc.) have disappeared on their own.

                                       

                                      I hope this at least helps point you in the right direction.