Author Topic: Layouts and Listboxes and other L-words..  (Read 3573 times)

0 Members and 1 Guest are viewing this topic.

hardwired

  • Guest
Layouts and Listboxes and other L-words..
« on: April 01, 2008, 07:17:22 AM »
Hi,

On a new program i have a listbox which is populated by the current drawing's layouts and the main point of the program is to add / edit revision data to the titleblocks..

I have it running so that it updates the current layout, but after now adding the listbox, what i want is to have the user select the required layouts from the listbox, so could be one, three, all etc..

These are the bits and pieces i'm stuck on, so any help would be much appreciated:


1: How can i code it to find out which layouts the user selects, then loops through only these to update the titleblocks?

2: I want a Select All checkbox - so how can i program it to select all entries in the listbox..

3: When the form first loads, i want the current layout to be the only selected entry in the listbox, likewise, if the user unchecks the Select All checkbox, i want it to resort back to only the current layout selected..

Thanks..

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16721
  • Superior Stupidity at its best
Re: Layouts and Listboxes and other L-words..
« Reply #1 on: April 01, 2008, 08:44:24 AM »
Listboxes are notorious for being a little stubborn to work with. Ok .. not stubborn, but a little unintuitive.

To be able to select multiple items in the listbox, set the multiselect property to frmMultiSelectMulti (1)

To determine what items are selected, you will need to loop through the listbox and check each item

Code: [Select]
Private SelectedLayouts() As String

Private Sub ListBox1_Change()
    Dim X As Integer
    ReDim SelectedLayouts(0)
'loop through the listbox
    For X = 0 To ListBox1.ListCount - 1
'if an item is selected
        If ListBox1.Selected(X) = True Then
'then increment our array and add it to the array
            ReDim Preserve SelectedLayouts(UBound(SelectedLayouts) + 1)
            SelectedLayouts(UBound(SelectedLayouts)) = ListBox1.List(X)
        End If
    Next X
End Sub

Now you have an array with all of the selected layouts

The SelectedLayouts() variable definition should be placed in the declarations portion of the form so it is available globally to the rest of your form.

Now to select all items in the listbox using a checkbox.

Code: [Select]
Private Sub CheckBox1_Click()
 Dim X As Integer
 For X = 0 To ListBox1.ListCount - 1
    ListBox1.Selected(X) = CheckBox1.Value
 Next X
End Sub

Cheers
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

hendie

  • Guest
Re: Layouts and Listboxes and other L-words..
« Reply #2 on: April 01, 2008, 08:51:40 AM »
and you should be aware that the dxf code 410 to filter layouts doesn't work in VBA

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16721
  • Superior Stupidity at its best
Re: Layouts and Listboxes and other L-words..
« Reply #3 on: April 01, 2008, 09:10:57 AM »
Ah .. forgot that little tidbit of information
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

hardwired

  • Guest
Re: Layouts and Listboxes and other L-words..
« Reply #4 on: April 01, 2008, 10:10:36 AM »
Keith, you are a legend, you seem to help me everytime, so thanks..

Right got the select all thing and now got the array for the slected items, but now from this, how do i loop through the layouts using this array. I did have:

Code: [Select]
Dim Cx as Integer
For Cx = LBound(SelectedLayouts) To UBound(SelectedLayouts) - 1
   ThisDrawing.ActiveLayout = SelectedLayouts(Cx)
   ' blah blah blah code for revising stuff blah blah..
next Cx

Obviously For Cx = LBound(SelectedLayouts) To UBound(SelectedLayouts) - 1 just loops through the string values, so how do i pass them to the layouts. I thought that the ThisDrawing.ActiveLayout = SelectedLayouts(Cx) line would do that but i get a type mismatch error on that..


Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16721
  • Superior Stupidity at its best
Re: Layouts and Listboxes and other L-words..
« Reply #5 on: April 01, 2008, 10:21:18 AM »
Ok .. a couple of pointers ...

You don't need to set the ActiveLayout unless you are graphically selecting objects from the screen using the mouse or programmatically selecting them using coordinates. I suspect you want to do it programmatically and can modify the attributes by selecting the proper block to work with.

If you do need to set ActiveLayout, you will need to pass the Layout object, not just the name .. to do that ...

Code: [Select]
ThisDrawing.ActiveLayout = ThisDrawing.Layouts.Item(SelectedLayouts(Cx))

Now, presumably you are going to be selecting title blocks on each layout. To do this, all you need to do is get a collection of all the title blocks in the drawing and filter them based on the layout they are in. It is a little tricky as hendie mentioned .. there is no filter for layout in VBA ... so you have to actually check the layout property of each block reference you have selected.
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

hardwired

  • Guest
Re: Layouts and Listboxes and other L-words..
« Reply #6 on: April 01, 2008, 10:39:01 AM »
I get a Key Not found error on the ThisDrawing.ActiveLayout = ThisDrawing.Layouts.Item(SelectedLayouts(Cx)) line you gave me..

Yeah, i do want to access the titleblocks without looping through the layouts if i can and its not too hard. Up until now, all the stuff for updating titleblocks and attributes on these blocks i have done by physically looping through each layout, but sometimes due to regen times, this can be so time consuming. If i can't filter the layouts in VBA, how do do it?

hendie

  • Guest
Re: Layouts and Listboxes and other L-words..
« Reply #7 on: April 01, 2008, 10:50:05 AM »
check the value of SelectedLayouts(Cx) in the locals window... you definitely made it global didn't you ?

you can filter the layouts in vba, you just can't use the 410 dxf code, which makes it a bit more involved

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16721
  • Superior Stupidity at its best
Re: Layouts and Listboxes and other L-words..
« Reply #8 on: April 01, 2008, 10:58:14 AM »
The problem is that in the code I provided (and you subsequently used) I have initialized SelectedLayouts with 0, then increment from there. The reason I did this is because the count is not zero based .. i.e. Layout #3 = SelectedLayouts(3) .. you should begin your loop at LBound(SelectedLayouts) + 1 and end it at UBound(SelectedLayouts) .. or alternatively you could revise the code I provided to begin storing at index 0 instead of index 1
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

hardwired

  • Guest
Re: Layouts and Listboxes and other L-words..
« Reply #9 on: April 01, 2008, 12:16:12 PM »
Brilliant Keith, thanks so much nearly there now, just need to sort out getting the current layout (the program goes to paperspace when run) to be highlighted in the listbox - how can i achieve that?

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16721
  • Superior Stupidity at its best
Re: Layouts and Listboxes and other L-words..
« Reply #10 on: April 01, 2008, 02:38:26 PM »
Not sure I understand what you are looking to do .. do you want to go to paperspace in the layout selected in the list? If so, you will create a problem when you select more than one layout from the list.

I mentioned earlier that you could filter the title blocks into a selection set and only operate on the ones you selected.

This utility will return the block if it exists, otherwise it returns nothing. You will have to verify the block actually exists before operating on it.

Code: [Select]
Function GetBlockReferenceByLayout(ByVal strBlockName As String, ByVal strLayoutName As String) As AcadBlockReference

'setup variables
Dim BLCollect As AcadSelectionSet
Dim BlkRef As AcadBlockReference
Dim GCode(1) As Integer
Dim GData(1) As Variant
Dim GPCode As Variant
Dim GPData As Variant

'filter for selection set
GCode(0) = 0
GData(0) = "Insert"
GCode(1) = 2
GData(1) = strBlockName
GPCode = GCode
GPData = GData

'create selection set
Set BLCollect = ThisDrawing.SelectionSets.Add("BLOCKREF")
'add items to selection set
BLCollect.Select acSelectionSetAll, , , GPCode, GPData
'loop through all items in selection set
For Each BlkRef In BLCollect
    'compare layout name
    If UCase(ThisDrawing.ObjectIdToObject(BlkRef.OwnerID).layout.Name) = UCase(strLayoutName) Then
        'return the reference
        Set GetBlockReferenceByLayout = BlkRef
        Exit For 'exit the 'for' loop since we have the title block. This assumes only a single block in each layout
    End If
Next BlkRef

'delete the selection set
BLCollect.Delete
'clear the variable
Set BLCollect = Nothing
End Function

Usage should be in the following format ...
Code: [Select]
Dim blkObject As AcadBlockReference
Set blkObject = GetBlockReferenceByLayout("titleblock", "layout1")
If blkObject = Nothing Then
 MsgBox "titleblock was not found in layout1"
Else
 'do other stuff here to blkObject
End If
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

hardwired

  • Guest
Re: Layouts and Listboxes and other L-words..
« Reply #11 on: April 01, 2008, 03:27:16 PM »
I don't want to go the layout that is selected, i have forced the program to go to paperspace when it loads, but won't need to now with your code but before it would simply go to the last layout that was used in normal draughting and thats why i wanted the current layout to be highlighted in the listbox becuase originally the program only did one layout (the current one). but as with the code you provided i don't have to cycle through the layouts physically, i don't need it anymore, all i need to do is error trap for no layouts selected in the listbox..

but for future reference and my own thirst for knowledge, how would i code the listbox to highlight the current layout?

For some reason also, the code you gave for select all on the listbox won't work anymore, it only selects one - the only alteration to your code was renaming the control and changing its ListStyle property to 1 - fmListStyleOption. it worked fine when i first used it but for some reason it won't now, even if i change the liststyle again..

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16721
  • Superior Stupidity at its best
Re: Layouts and Listboxes and other L-words..
« Reply #12 on: April 01, 2008, 04:09:40 PM »
multiselect must be set to frmMultiSelectMulti or it will fail.

To get the current layout to highlight, while populating the listbox, check to see if the layout name matches the one currently being added. If it does, then highlight. Remember the count of the listbox is -1 from the listbox index.

Code: [Select]
With ListBox1
'populate the listbox
 For Each layout In layouts
   .AddItem layout.Name
'if the current layout matches the layout just added then select it
   If layout.Name = ThisDrawing.ActiveLayout.Name Then
    ListBox.Selected(.ListCount - 1) = True
   End If
 Next

Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

hardwired

  • Guest
Re: Layouts and Listboxes and other L-words..
« Reply #13 on: April 02, 2008, 05:48:22 AM »
Again thanks..

Now i need to sort out this Select All checkbox..

I noticed that if i remove the following code you provided:

Code: [Select]
Private Sub LayoutLIST_Change()
ReDim SelectedLayouts(0)
'loop through the listbox..
For X = 0 To LayoutLIST.ListCount - 1
'if an item is selected
    If LayoutLIST.Selected(X) = True Then
    'then increment our array and add it to the array..
        ReDim Preserve SelectedLayouts(UBound(SelectedLayouts) + 1)
        SelectedLayouts(UBound(SelectedLayouts)) = LayoutLIST.List(X)
    End If
Next X
End Sub


...from the Listbox's change event, the Select All code you provided:

Code: [Select]
Private Sub SelectAll_CHK_Click()
For X = 0 To LayoutLIST.ListCount - 1
    LayoutLIST.Selected(X) = SelectAll_CHK.Value
Next X
End Sub

.....works. But of course i need the array set-up from the listbox's change event, so is there any other way to select all entries in the listbox other than the way you first gave?

This is my final hurdle on this program, well for now, i'm sure i'll find other way to improve things on it or add functionality but for now, this is it..

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16721
  • Superior Stupidity at its best
Re: Layouts and Listboxes and other L-words..
« Reply #14 on: April 02, 2008, 08:37:12 AM »
I don't understand what you are trying to accomplish, but the code works as posted. When you select the items using your SelectAll_CHK_Click event, it will fire the LayoutLIST_Change event, not once, but once for each change made.
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal