Populate activeX comboboxes on different generated sheets (Excel 2007) - vba

i'm a beginner and it's been days since i'm looking for a solution in vain, here's my issue:
In my excel file i should generate different sheets with a macro (already done).
Now on a specified column "L" on all of these generated sheets (starting from sheet number 9), i need an activeX combobox that would contain values brought from un unlimited column(A) of sheet(6).
I started by getting the values by adding values <> "" and storing them in an array.
it's not working, it's all messy, can someone please correct my code and help me, i'd appreciate any help .. thank you in advance
Option Explicit
Sub PicklistCopy()
Dim Nbre As Byte, Arr(), Liste As String, Cptr As Byte
Dim Current As Worksheet
Dim strSearch As String
Dim aCell As Range
strSearch = "Pick List Name"
For Each Current In Worksheets
Set aCell = Rows(1).Find(What:=strSearch, LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
'copy pl values in an array
With Sheets("Pick Lists")
Nbre = Application.CountA(.Range("MyPL"))
ReDim Arr(1 To .Range("MyPL").Count)
Arr = Application.Transpose(.Range("MyPL"))
End With
'Get values diff from null
For Cptr = 1 To UBound(Arr)
If Arr(Cptr) <> "" Then Liste = Liste & Arr(Cptr) & ";"
Next
Liste = Left(Liste, Len(Liste) - 1)
With ActiveSheet.Range("L2:L4").Validation
.Delete
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
xlBetween, Formula1:=Liste
.IgnoreBlank = True
.InCellDropdown = True
End With
ActiveSheet.Range("L2:L4") = ""
Next
End Sub

I think what you are adding is Data Validation dropdown and not a regular dropdown. Below is my simple code to the the list under the validated cell.
Sub AddMyPl()
Dim ws As Worksheet
Dim strSearch As String
Dim aCell As Range
strSearch = "Pick List Name"
'This will loop thru my sheets in my workbook.
For Each ws In ActiveWorkbook.Worksheets
'skip the sheet that contains mylist
If ws.Name <> "mylist" Then
'get last row # in L column.
LastR = ws.Cells(Rows.Count, "L").End(xlUp).Row
'add validation from MyPL list to cells
With ws.Range("L2:L" & LastR).Validation
.Delete
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
xlBetween, Formula1:="=MyPL"
.IgnoreBlank = True
.InCellDropdown = True
End With
End If
Next ws
End Sub
I have 4 sheets. 'mylist' sheet contains MyPL range with the items for my dropdown. The loop will check all sheets which names is not "mylist" then will add the validation dropdown to range L2:L4.
Modify as needed.

Related

sorting for worksheets in 1 workbook

I have searched the net for a macro that can help me to do sorting for worksheets in a workbook and modified it a little ( adding the exclude worksheets)
Sub SortDataWorksheets()
Dim wsh As Worksheet
For Each wsh In ThisWorkbook.Sheets
If wsh.Name <> "Dashboard" And wsh.Name <> "rawdata" And wsh.Name <> "template" And wsh.Name <> "macros instructions" And wsh.Name <> "Sheet1" _
And wsh.Name <> "Sheet2" And wsh.Name <> "inputlist" And wsh.Name <> "ProductList" And wsh.Name <> "NA" Then
'sort columns A to AL based on data in column B
wsh.Columns("A:AL").Sort key1:=Range("B3"), order1:=xlAscending, Header:=xlYes
End If
Next
End Sub
However, this doesnt work as excel will throw the
Run Time error '1004' :
The sort reference is not valid. Make sure that it's within the data you want to sort...
My data starts from Row 3 onwards, 1st 2 rows are headers. How do i exclude the first 2 rows for sorting?
Change from:
wsh.Columns("A:AL").Sort key1:=Range("B3"), order1:=xlAscending, Header:=xlYes
To:
wsh.Columns("A:AL").Sort key1:=wsh.Range("B3"), order1:=xlAscending, Header:=xlYes
Because if you do not refer to the parent worksheet, VBA takes as parent worksheet the ActiveSheet or the sheet in which the code is. Both would return an error in your case.
This works for me:
Sub SortDataWorksheets()
Dim wsh As Worksheet
Dim LastRow As Long
For Each wsh In ThisWorkbook.Sheets
With wsh
If .Name <> "Dashboard" And .Name <> "rawdata" And .Name <> "template" And _
.Name <> "macros instructions" And .Name <> "Sheet1" _
And .Name <> "Sheet2" And .Name <> "inputlist" And _
.Name <> "ProductList" And .Name <> "NA" Then
LastRow = .Cells.Find(What:="*", SearchOrder:=xlRows, SearchDirection:=xlPrevious, LookIn:=xlValues).Row
'sort columns A to AL based on data in column B
.Range("A2:AL" & LastRow).Sort key1:=.Range("B3"), order1:=xlAscending, Header:=xlYes
End If
End With
Next
End Sub
Notice the use of a specific range instead of columns.
I find it easier to read a Select Case rather than multiple IF..AND..THEN when ignoring sheets.
The code below will adjust to how many rows contain data in column B.
I'm still not sure which is the preferred method of sorting - single line, or what the macro recorder returns (similar to below).
Public Sub SortDataWorksheets()
Dim wsh As Worksheet
Dim lLastRow As Long
For Each wsh In ThisWorkbook.Worksheets
Select Case wsh.Name
Case "Dashboard", "rawdata", "template", "macros instructions", _
"Sheet1a", "Sheet2a", "inputlist", "ProductList", "NA"
'Do nothing
Case Else
lLastRow = wsh.Cells(wsh.Rows.Count, 2).End(xlUp).Row
With wsh.Sort
With .SortFields
.Clear
.Add Key:=Range("B5:B" & lLastRow), _
SortOn:=xlSortOnValues, _
Order:=xlAscending, _
DataOption:=xlSortNormal
End With
.SetRange Range("A5:C" & lLastRow)
.Header = xlNo
.MatchCase = False
.Orientation = xlTopToBottom
'.SortMethod = xlPinYin 'Only need if sorting Chinese characters.
.Apply
End With
End Select
Next wsh
End Sub

How to add an array into an in cell dropdown from a scripting dictionary?

I have a data dump from different application. I want to get unique values from a singular column in the data dump (which has variable length). Once I have the unique values I want them to be called into an .incelldropdown from data validation. I've figured out most of this except for the last part where I get the error:
Runtime Application Error: "1004" Application or object defined error.
See below:
Sub TitleRange()
Dim sheet As Worksheet
Dim LastRow As Long
Dim StartCell As Range
Dim RangeArray As Variant
Worksheets("Raw").Select
Set sheet = Worksheets("Raw")
Set StartCell = Range("A2")
'Find Last Row
LastRow = Cells(Rows.Count, "A").End(xlUp).Row
'Select Range & load into array
RangeArray = sheet.Range("A2:A" & LastRow).Value
Dim d As Object
Set d = CreateObject("Scripting.Dictionary")
Dim i As Long
For i = LBound(RangeArray) To UBound(RangeArray)
d(RangeArray(i, 1)) = 1
Next i
Dim v As Variant
For Each v In d.Keys()
'd.Keys() is a Variant array of the unique values in RangeArray.
'v will iterate through each of them.
Next v
'This code below gives me a problem
Worksheets("PR Offer Sheet").Select
Range("C1").Select
With Selection.Validation
.Delete
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:=d.Keys()
.InCellDropdown = True
End With
The debugger says the problem is the d.Keys() from scripting. However, I've tried to convert into a string using Join (d.Keys(), ",") and calling that new variable in the data validation which yields same error. I am running this on Excel 2010.
I thought this also might be a problem that the variant array is 2D and it needs to be 1D but that doesn't seem to be the case.
This works for me. xlValidateList is expecting a list separated by commas (or a range). I have also removed the Select and Activate statements which are not needed and slow code down.
Sub TitleRange()
Dim sheet As Worksheet
Dim LastRow As Long
Dim RangeArray As Variant
Dim i As Long
Dim d As Object
Set sheet = Worksheets("Raw")
With sheet
'Find Last Row
LastRow = .Cells(Rows.Count, "A").End(xlUp).Row
'Select Range & load into array
RangeArray = .Range("A2:A" & LastRow).Value
End With
Set d = CreateObject("Scripting.Dictionary")
For i = LBound(RangeArray) To UBound(RangeArray)
d(RangeArray(i, 1)) = 1
Next i
With Worksheets("PR Offer Sheet").Range("C1").Validation
.Delete
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:=Join(d.Keys, ",")
.InCellDropdown = True
End With
End Sub
This appears to work:
Sub MAIN2()
Dim it As Range, r As Range, x0, s As String
With CreateObject("scripting.dictionary")
For Each it In Sheets("Raw").Columns(1).SpecialCells(2).Offset(1)
x0 = .Item(it.Value)
Next
s = Join(.Keys, ",")
End With
With Worksheets("PR Offer Sheet").Range("C1").Validation
.Delete
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:=s
.InCellDropdown = True
End With
End Sub

Search again if not found

So I have a part in my macro that I want to add what I assume needs to be an "Else" portion, but I am not that good with macros and am asking for help.
Range("Z1").Copy
Dim FindString As String
Dim Rng As Range
FindString = Sheets("Pull").Range("Y1").Value
If Trim(FindString) <> "" Then
With Sheets("HourTracker").Range("A:A")
Set Rng = .Find(What:=FindString, _
After:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not Rng Is Nothing Then
Application.Goto Rng, True
Else
MsgBox "Nothing found"
End If
End With
ActiveCell.Offset(0, 1).Activate
Selection.PasteSpecial xlPasteValues
Application.DisplayAlerts = True
End If
End Sub
So what I want this to do, is instead of "MsgBox "Nothing Found"", I want it to essentially perform the same thing as above, but copy cell Z2, and search for the value of Y2 in the same sheet "HourTracker" then paste the value. I have no idea on how to accomplish this, and all my attempts have failed. Any help would be much appreciated. Let me know if you need more clarification, thank you in advance!!!
Sounds to me like you're looking for a loop.
Sub findStuff()
Application.DisplayAlerts = False
' The item you want to paste
Dim PasteString As String
' The item you're looking for
Dim FindString As String
' The range that may containing FindString
Dim Rng As Range
' The variable used to loop through your range
Dim iCounter as Long
' loop through the first cell in column Y to the last used cell
For iCounter = 1 To Sheets("Pull").Cells(Rows.Count, 25).End(xlUp).Row
' PasteString = the current cell in column Z
PasteString = Sheets("Pull").Cells(iCounter, 26).Value
' FindString = the current cell in column Y
FindString = Sheets("Pull").Cells(iCounter, 25).Value
If Trim(FindString) <> "" Then
With Sheets("HourTracker").Range("A:A")
' Find the cell containing FindString
Set Rng = .Find(What:=FindString, _
After:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not Rng Is Nothing Then
' There's no need to activate/ select the cell.
' You can directly set the value with .Value
Rng.Offset(0, 1).Value = PasteString
Else
' Do nothing
End If
End With
Else
' Do nothing
End If
Next
Application.DisplayAlerts = True
End Sub
Every time the compiler hits Next it will start again at For but raise the value of iCounter by 1. We can use Cells to accomplish this since Cells takes the row and column arguments as numbers, not strings (like Range). The syntax is simply Cells(Row #, Column #). Therefore, every time the For . . . Next loops around again, iCounter will go up by one and you'll search in the next row.
Instead of using .Paste, you can set the value of a cell directly with .Value. Pasting is pretty slow and using .Value is much faster.
Cells().End(xlUp).Row is a method used to find the last used cell in a range. See Error in finding last used cell in VBA for a much better explanation than I can give here.

How to alter code with FOR Each Loop to to avoid Error: 1004 No cells found

I have a macro that looks below header names for items if there is an item it will make it a drop down. Headers are in the 7th row so it starts looking from row 8 and on. The code runs perfectly, except if there is no items below the headers.
Sometimes the user does not need any drop downs for the sheet so they will leave all rows below the headers blank. Which is great for what I am doing but will make the macro throw errors as there is no items to be found.
I essentially need to tweak my code so it is able to stop or exit if no cells are found. This is the macro I need to tweak.
Sub AddDropDowns()
Dim cell As Range
Dim iDropDown As Long
With Worksheets("Sheet1")
For Each cell In .Range("B8", .Cells(8, .Columns.Count).End(xlToRight)).SpecialCells(XlCellType.xlCellTypeConstants)
AddDropDown Worksheets("DropDownsTT"), iDropDown, cell.Offset(-1).Value, "='" & .Name & "'!" & cell.Resize(WorksheetFunction.CountA(cell.EntireColumn) - 1).Address
Next cell
End With
End Sub
Not sure if this piece of code is needed but the macro calls the following subroutine:
Sub AddDropDown(sht As Worksheet, dropDownCounter As Long, header As String, validationFormula As String)
With sht.Range("A1").Offset(, dropDownCounter) '<--| reference passed sheet row 1 passed column
.Cells(1, 1) = header '<--| write header
With .Cells(2, 1).Validation '<--| reference 'Validation' property of cell 1 row below currently referenced one
.Delete
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:=validationFormula
.IgnoreBlank = True
.InCellDropdown = True
.InputTitle = ""
.ErrorTitle = ""
.InputMessage = ""
.ErrorMessage = ""
.ShowInput = True
.ShowError = True
End With
End With
dropDownCounter = dropDownCounter + 1
End Sub
You could do this:
Dim rng As Range
'...
With Worksheets("Sheet1")
On Error Resume Next
Set rng = .Range("B8", .Cells(8, .Columns.Count).End( _
xlToRight)).SpecialCells(XlCellType.xlCellTypeConstants)
On Error Goto 0
If Not rng Is Nothing Then
For Each cell In rng
AddDropDown Worksheets("DropDownsTT"), iDropDown, _
cell.Offset(-1).Value, "='" & .Name & "'!" & _
cell.Resize(WorksheetFunction.CountA(cell.EntireColumn) - 1).Address
Next cell
End If
End With
but that's kind of untidy, so I would probably use something like:
With Worksheets("Sheet1")
For Each cell In .Range("B8", .Cells(8, .Columns.Count).End( xlToRight))
If Len(cell.Value) > 0 Then
AddDropDown Worksheets("DropDownsTT"), iDropDown, _
cell.Offset(-1).Value, "='" & .Name & "'!" & _
cell.Resize(WorksheetFunction.CountA(cell.EntireColumn) - 1).Address
End If
Next cell
End With

VBA for searching string in a column and copy entire rows depending on the presence of certain string at adjacent cell

I am completely new for VBA.
I have excel data sheet containing numbers and strings. I want to search for certain string say 'CYP' in column I then look for a cell of its row at column C and copy entire rows containing the string of cell C. I want to paste in sheet 2 of the same workbook and loop it again to look for remaining CYPs in column.
Would you help me on this please?
After the suggestion from pnuts, here is my macro code
Sub Macro1()
'
' Macro1 Macro
'
'
Columns("I:I").Select
Range("I729").Activate
Selection.Find(What:="cyp", After:=ActiveCell, LookIn:=xlValues, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False).Activate
ActiveWindow.SmallScroll Down:=5
Range("C749").Select
Selection.Copy
Columns("C:C").Select
Range("C734").Activate
Selection.Find(What:="EPT001TT0601C000151", After:=ActiveCell, LookIn:= _
xlValues, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext _
, MatchCase:=False, SearchFormat:=False).Activate
Rows("746:750").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Sheet2").Select
ActiveSheet.Paste
End Sub
In this code the CYP was found in I749, cell C749 was copied as string and first row in column C containing the same string was searched followed by copying of the entire row and 4 more followed by it then pasting in sheet2 of the same workbook.
What I wanted was to loop this action again and again upto the end of column I and repeat the same action.
Thank you!
I managed to solve the problem with the help of Trebor76 at Excelforum. Here I am giving solution in that way it might be helpful for some newbies like myself with similar problem.
Option Explicit
Sub Macro1()
'Written and assisted by Trebor76
'Copy an entire row from Sheet1 to Sheet2 for each unique matching item in Col. C if the text in Col. I contains the text 'CYP' (case sensitive)
'http://www.excelforum.com/excel-programming-vba-macros/962511-vba-for-searching-string-in-a-column-and-copy-rows-depending-on-string-in-adjacent-cell.html
Dim rngCell As Range
Dim objMyUniqueArray As Object
Dim lngMyArrayCounter As Long
Dim lngMyRow As Long
Dim varMyItem As Variant
Application.ScreenUpdating = False
Set objMyUniqueArray = CreateObject("Scripting.Dictionary")
For Each rngCell In Sheets("Sheet1").Range("I1:I" & Sheets("Sheet1").Range("I" & Rows.Count).End(xlUp).Row)
If InStr(rngCell, "CYP") > 0 Then
If Not objMyUniqueArray.Exists(Trim(Cells(rngCell.Row, "C"))) Then
lngMyArrayCounter = lngMyArrayCounter + 1
objMyUniqueArray.Add (Trim(Cells(rngCell.Row, "C"))), lngMyArrayCounter
varMyItem = Sheets("Sheet1").Cells(rngCell.Row, "C")
For lngMyRow = 1 To Sheets("Sheet1").Cells(Rows.Count, "C").End(xlUp).Row
If Sheets("Sheet1").Cells(lngMyRow, "C") = varMyItem Then
Rows(lngMyRow).Copy Destination:=Sheets("Sheet2").Range("A" & Sheets("Sheet2").Range("A" & Rows.Count).End(xlUp).Row + 1)
End If
Next lngMyRow
End If
End If
Next rngCell
Set objMyUniqueArray = Nothing
Application.ScreenUpdating = True
MsgBox "All applicable rows have been copied.", vbInformation
End Sub
Cheers!