• Hi All

    Please note that at the Chandoo.org Forums there is Zero Tolerance to Spam

    Post Spam and you Will Be Deleted as a User

    Hui...

  • When starting a new post, to receive a quicker and more targeted answer, Please include a sample file in the initial post.

Please help with input form, arrays and a function

jbaich

Member
Hi everybody and thanks in advance for your help!
smile.gif
and sorry if my terminology is wrong, please feel free to correct me where this is the case

I have posted this thread on another forum as well, but so far no luck. I am hoping somebody on this forum will be able to help me out...

Basically I've got 3 bits of code that i'm trying to stitch together and am only 1/2 way through my VBA for Dummies book...
smile.gif


What i'm trying to do is create an input form that appears with 2 options. Based on the option selected, one of 2 ranges will be identified and passed through to a function procedure as the input array.... after the function runs, I would like it's results (another array) to be passed through as the elements(?) or variables(?) for another array in the sub procedure...

I have never used input forms before so i'm kind of lost right off the bat and i'm only really just starting to understand what my macro recorder's been doing for me all these years!
smile.gif


Currently I have a macro that creates what you see in the attached sample workbook... I would at this point run the code in Step 3 below, but I would like to modify it by adding Setp 1 and 2 below at this point...

Step 1- User input... I have no idea how this is supposed to go, but I would like (see code below...) "OptionModelType" to select Range(=LEFT(B30:End(xlToRight),3) ie. In the last part of code below (Step 3) the code enters the first 3 characters of cell30 into cell1 for each column... if I do this first, then the desired range would be B1:B (last column), obviously if the user input box is going to work here I will have to move that process to have already occurred before this point unless the range can be determined without this step at all? "OptionModelName" is basically the same range except for the full value of the cells in row 30 and not just the first 3 characters.

Code:
'No Idea What I'm supposed to do here...'
 
Private Sub UserForm_Click()
 
End Sub
 
Private Sub OptionModelType_Click()
 
End Sub
 
Private Sub OptionModelName_Click()
 
End Sub
 
Private Sub GoButton1_Click()
End Sub

Once the user has made a selection and clicked "Go", I would like the selected range to be used as the input array in this function... By the way, this function has an optional count operation that I don't need, i'm just not 100% sure which code I can delete without messing it up, so I would like to have Count set to False automatically all the time or just lose the count feature.

Step 2- The UniqueItems Function

Code:
Option Base 1
 
Function UniqueItems(ArrayIn, Optional Count As Variant) As Variant
'  Accepts an array or range as input
'  If Count = True or is missing, the function returns the number of unique elements
'  If Count = False, the function returns a variant array of unique elements
    Dim Unique() As Variant ' array that holds the unique items
    Dim Element As Variant
    Dim i As Integer
    Dim FoundMatch As Boolean
'  If 2nd argument is missing, assign default value
    If IsMissing(Count) Then Count = True
'  Counter for number of unique elements
    NumUnique = 0
'  Loop thru the input array
    For Each Element In ArrayIn
        FoundMatch = False
'      Has item been added yet?
        For i = 1 To NumUnique
            If Element = Unique(i) Then
                FoundMatch = True
                Exit For '(exit loop)
            End If
        Next i
AddItem:
'      If not in list, add the item to unique list
        If Not FoundMatch And Not IsEmpty(Element) Then
            NumUnique = NumUnique + 1
            ReDim Preserve Unique(NumUnique)
            Unique(NumUnique) = Element
        End If
    Next Element
'  Assign a value to the function
    If Count Then UniqueItems = NumUnique Else UniqueItems = Unique
End Function

Finally this function produces a list of all the unique values in the input array, but rather than having them copied into cells, (unless that's a necessary step...) I would like this list of values to be passed through as the array elements for VArray in this next bit... ie. VArray = Array("results from this function... if i'm understanding this right that would be NumUnique()?" instead of the hard keyed variables in the code below)

Step 3- The rest... FYI I also don't want to delete any worksheets, but for some reason the code doesn't seem to delete them anyway... again, have been hesitant to remove any lines as the code still functions as is
smile.gif

Code:
Sub sSplitData()
 
Dim wsOriginal As Worksheet
Dim ws As Worksheet
Dim wsMaster As Worksheet
Dim lLC As Long, i As Long
Dim vElement, vArray
vArray = Array("IND", "OFF", "RET") ' Trying to get these elements input from previous function... ie NumUnique()'
Dim rDelete As Range
 
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
On Error Resume Next
 
Set wsOriginal = Sheets("Sheet3")
 
' delete all worksheets first (except the original)
For Each ws In ThisWorkbook.Sheets
    Application.DisplayAlerts = False
    If ws.Name <> wsOriginal.Name Then
        ws.Delete
    End If
    Application.DisplayAlerts = True
Next 'ws
 
' make a copy of the original and name it "Master"
wsOriginal.Copy after:=Sheets(Sheets.Count)
Set wsMaster = ActiveSheet
wsMaster.Name = "Master"
 
' add column headings to "Master" worksheet...................... ' will need to move this earlier to before input form unless range can be determined without physically adding these values to row 1???'
With wsMaster
    lLC = .Cells(4, .Columns.Count).End(xlToLeft).Column
    For i = 2 To lLC
        .Cells(1, i).Value = _
            Left(.Cells(30, i).Value, 3)
    Next 'i
End With
 
' copy Master worksheet to individual sheets
Application.DisplayAlerts = False
For Each vElement In vArray
    wsMaster.Copy after:=Sheets(Sheets.Count)
    Set ws = ActiveSheet
    ws.Name = vElement
Next 'vElement
Application.DisplayAlerts = True
 
' delete Master worksheet
Application.DisplayAlerts = False
'wsMaster.Delete
Application.DisplayAlerts = True
 
' delete columns on each sheet
For Each vElement In vArray
    Set ws = Sheets(vElement)
    With ws
        lLC = .Cells(1, .Columns.Count).End(xlToLeft).Column
        For i = 2 To lLC
            If .Cells(1, i).Value <> vElement Then
                If rDelete Is Nothing Then
                    Set rDelete = .Cells(1, i)
                Else
                    Set rDelete = Union(rDelete, .Cells(1, i))
                End If
            End If
        Next 'i
        If Not rDelete Is Nothing Then
            rDelete.EntireColumn.Delete
        End If
        Set rDelete = Nothing
    End With
Next 'vElement
 
' tidy up
On Error GoTo 0
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
 
End Sub

I have attached a sample worksheet and any help would be very much appreciated! Also, in the original workbook, many of the values have formulas and vlookups, but in order to keep this small and simple I've just included values and formats in this sample...

Many Thanks,
Joe
 

Attachments

  • sample3.xlsm
    485.9 KB · Views: 6
Joe

Instead of asking us to put this code in here etc, Can you tell us what your trying to achieve

From my Take:

Step 3 which is ran first copies each of the 3 Building types to its own worksheets, This runs fine as is.
Although it doesn't delete the non-compliant pictures when it deletes the Columns

Step 2 is about Unique items and so I assume you want to do something with checking for duplicates ?

Step 1 Looks like you want the user to have some options

so:

I assume you want a button on Sheet3 which you will click to run/open a userform

What do you want on the userform Buttons/Data etc?

What should happen when you click each button on the userform?

If you don't want a user form what isn't step 3 doing now that you want it to do
ie: Sort the Properties Left to right in decreasing value

Use plain English, don't talk about Arrays, procedures and functions
There are always a few ways to do everything in Excel and understanding what your trying to achieve is more important than the code.
 
Hi Hui, thanks for your reply!

Yes you got it right, as it goes right now, the "Step 3" code copies the main sheet into separate sheets and then deletes columns so that each sheet contains only related columns based on the values in row 30. Right now, these are predetermined as "RET", "IND", and "OFF". Rather than have these static, predetermined values, i would like to create an input form that allows the user to choose if they want the sheets to be created based on the first 3 characters of the row 30 cell values, similar to what appears now, but capable of being dynamic so that if a data set contains "APT" that sheet would be created or if there are no "RET" records, that sheet would not be created.

option B for the user would be to create a sheet for each unique value in row 30, not just based on the first 3 characters... so in one instance it may create 3 sheets, one for each of RET1234, RET2345, and OFF5555... or in another instance it may be a dozen sheets, each exclusive to a unique value in Row 30...

I think i need to define each choice on the user form as a range, and then the user chooses one and when they click the "go" button, which then populates the selection as the inputs for step 2, but i don't know how to write that... dim option1 as range or variant or element? Completely out of my comfort zone and just trying to understand everything... :)

so the user chooses the preferred method, the unique values are calculated based on that choice and the new sheets are created, and unwanted columns deleted; and you're right about the images... I'm finding those are tricky to work within excel, but i figure function before beauty in this case... i can try to learn how to deal with images after i get the rest of it working if i have to.

Any advice would be very much appreciated :)

Cheers,
Joe
 
oh, and i just realized i missed responding to a point in your reply... i don't really want or need a button to activate the user form, i'd kinda like it to just open up automatically. This is actually about the 80% mark of the whole macro so there is code that runs prior to the code i'm trying to get working here and if the user form could just open automatically at this point, that would be awesome!

The user form would just ask the user if they would like to continue by sorting the data by model type (ie. RET, IND, OFF) or by model name (IE. RET1234, OFF5555, etc.) The user would choose (i was thinking radio button?) and then hit "GO" or "OK" or whatever and the macro would continue to the end.

Step 3 is great, it's just static... and there are potentially many options it would miss or do unnecessarily depending in the data which will be different every time.

hopefully that is a more clear description of the idea, please let me know if i can explain anything more and i will do my best!

Cheers,
Joe
 
Joe
What to do about values in Row 30 that are blank eg: N30
Do you want them reported as blank ?
 
just occurred to me "run the query" might be the wrong phrase... i meant more like hit the "go" button to continue with the macro :)

Cheers,
Joe
 
Do you want to Sort or Extract the model types as your current code copies them and puts each type on an individual sheet

Please clarify exactly what you want ?
 
extract is what i was going for, sort would work too, i just felt like that was impossible :) I still think extract is probably the better option, but whichever is easier or more stable is great!
 
I have changed the base sheet from Sheet 3 to Master, Sheet 3 just didn't work for me
You will see that the temporary sheet that is made is named after the matching criteria

Also gives a warning about blank cells in Row 30
Add a message showing how many records will be selected

You can now go back and change Combobox 1 values and Combobox 2 resets

upload_2014-11-22_22-34-22.png

Can you have a look at this and any feedback appreciated
 

Attachments

  • Sample 4.xlsm
    505 KB · Views: 10
Last edited:
Thanks Hui, i've only got a mac at home and when i opened your sample on it, there did not seem to be any macros attached to the workbook so i will try to run into the office later today to test it on a windows machine. I will let you know how it goes!

Thanks,
Joe
 
Hey Hui, just got home and checked out the sheet, it looks great! but i have a few questions... if there is a blank cell in row 30 can it just be a warning to the user that those records will not be included, allow them to cancel to go back and edit if they want, or choose to continue with the selection knowing that the blanks will not be included?

Also, can the user have the ability to extract based only on property type, which would include all properties in the RET, or OFF category rather than having to specify the model name? in some cases there may only be one or two records per model name and it would be more valuable to be able to see them all together on the same sheet just in a broader RET or OFF kind of category. Then in other instances where there are enough records per model name, that would be the more valuable category.

Is it possible to extract more than one, or all choices? maybe to a new book? I see that i can copy the extracted sheets to a new book and they maintain their data and structure just fine, which is great, just wondering if there could be bulk extract/copy/export kind of option? I don't know if I think this is a good idea just because that's kind of how it worked before and I'm a creature of habit or if it's actually beneficial... just thought i'd ask.

It also just occurred to me that I'm an idiot and should have mentioned that in the original workbook there are a couple of sheets that populate values in the master sheet with vlookups... will that cause any problems? will they be deleted on the refresh of the sort process?

Thanks,
Joe
 
Joe

Following changes made
1. Warns of a blank cell only and now keeps going
2. You can now extract the Property Type or Individual properties
3. You can now Save to a new Sheet or New Workbook
4. Save as Notification
5. Save Names

When saving as a Property Type File name is
IND 20141123.xlsx

When saving as a Property File name is
IND70457 20141123.xlsx

Where 20141123 is the date
IND Changes as the property type changes

See how that goes
 

Attachments

  • Sample 5.xlsm
    517.1 KB · Views: 6
Wow! I can't even believe my eyes!

The only issue i can see is the deleting sheets... as i mentioned before much of the data in this sheet is being pulled from other sheets in the original workbook, which if deleted will result in most of the cells containing REF# errors...is there anyway around this, maybe protecting these sheets somehow or excluding them from deletion via code? or should i just put in a line of code earlier in the macro that copies and pastes values and formats instead of referencing the other sheets? One of the other sheets in the original workbook is effectively the same "table" without the photos but in a horizontal rather than vertical format which allows the use of Excel's auto filters. This is often useful when there are many records so the user can filter down to specific criteria and see the corresponding column references to more quickly find the specific records they're after in the Master sheet. Definitely not a deal breaker to lose it, but it can be quite handy.

Is it possible to allow the user to choose the save location? or does it automatically save it in the same location as the active workbook?

Again, Thank you so much for all your help!

Cheers,
Joe
 
Have fixed up the #Ref errors by copying and pasting as values first
Now have option to Save as with user selectable directory and default file name is used but can be overwritten
 

Attachments

  • Sample 6.xlsm
    518.8 KB · Views: 7
Hey Hui, I tried to test out the code on a Full sized version of the report (which I have attached) that I am hoping to use this macro with and these are a couple of things I noticed...

1. The "Select" command button is not created in the current code, I thought I could macro recorder myself creating it but for some reason when I try to run the recorded code later, it gets hung up on a " .ThemeColor = 2 " line... not sure why or what I need to do to solve this. Does it do this when you try?

2. When I run the macro (without the Select button) everything seems to work, although there seem to be a couple of differences... The additional sheets are not deleted, even the last "extract" remains, which is totally fine with me and since the other sheets aren't deleted, the vlookups still work :)

3. It seemed in the samples we'd been using before that the photos were deleting with the columns and not piling up at the end of the last column anymore ( I could be wrong and just thought they were deleting ) and here they seem to be piling up again. No big deal, just curious if that means a line of code somewhere is not working as it did before? or if it was just because there were fewer columns in the sample sheet?

4. The initial warning message appears to loop through and present for each instance of a blank cell in Row 30, probably does not need to be a loop, I would think displaying once regardless of the number of blanks would be preferable, but again... pretty minor detail and no big deal.

I've attached the "Full Size" report, (although these will vary in size every time... but with the same sheets) Are you getting the same results I am? I guess the only really important thing to fix would be the creation of the "Select" command button... I don't know why there's a bug there.

Also, I don't know where to put or how to put the...

Code:
Private Sub Workbook_Open()
  Show_UserForm
End Sub

As this workbook will already be open and in effect, 1/2 way through a macro at this point... or does this code simply save into the workbook so that if it's saved and reopened in the future the user form opens in that situation?

UPDATE:

So I copied the private sub above into "This Workbook" and that seemed to make the delete all pages work... The sample sheet I have uploaded has the pre macro data with the macro's and forms attached to the workbook, except for the private sub function above... so you can see the pre deletion data :) Turns out all the photos have made the file size too large to upload here so I've put the link below to the file in dropbox.


https://www.dropbox.com/s/qs8ljrjeikc627h/Sample7b.xlsm?dl=0

Please let me know if it works as expected on your end.

Thanks again :)
Joe
 
Last edited:
UPDATE:)

So I switched the private sub in the worksheet to my "Add Select Button" macro instead of the "Show UserForm" and it sort of works if you skip the hangups, which now appear to be on .TintAndShade and .ThemeFont instead of .ThemeColor like before... Still no idea what's going on there... The only problem here is I don't know how to only add the button once... if I close the WB and then reopen it again later, it adds another button over the original button...

But anyways, skip those lines and it seems to work as expected... There did not appear to be anything in the last sample regarding copying the values and formats to prevent the REF# issue, but when I did before testing the macro it all seemed to work.

I can see as a remnant from the sSplitData way I was doing things before that there are still the 3 letter codes at the tops of the columns... just wondering if these serve any function anymore or can I get rid of them? as an experiment I tried ' commenting out ' the part of the code that creates them and it did seem to mess things up :(

Cheers,
Joe
 
Joe

I have made the following changes

0. Renamed Sheet3 to Master
1. Added new button to Master. You just add it don't need code
2. Fixed deletion of photos by column, this has slowed it down as it has to check each photo against each column
3. Added a Status Bar update message whilst it is doing the check in Pt 2 to ask you to wait
4. Fixed the initial warning message so that it only displays once
5. Added a new message if the new worksheet is added
6. Removed the 3 letters from Row 1 which was already done in the save file mode

It is saved in : https://dl.dropboxusercontent.com/u/65728154/Sample7c.xlsm

Enjoy
 
Hey Hui, It's beautiful! Thank you so much!

I don't understand how deleting the left over photos works... it seems like it does sometimes, but not every time? For example on your latest sample7c file, if I choose
1. APT 2. All properties 3. Save to new sheet in this workbook, the extra photos don't get deleted, but if I choose
1. RET 2. RET7414 3. Save to new sheet in this workbook, they do get deleted...

I was hoping I could figure it out myself, but I have no idea... It's not a big deal, I just don't understand and am curious how stuff works :)

Thanks again!
Joe
 
Back
Top