Excel dynamic drop downs based on previous selection - excel

Good day,
I could only find examples where the tables are quite simple and the data minimal. I'm sitting with 36 makes, and up to 3 072 variants on the below data which I need sorted out.
The below col A through E is an extract of my data, with col G through I, the selections I need to make. To explain.
Blockquote
Col G: Should be a drop down with the values from Col C (which is easy and is done already)
Blockquote
Col H: If I now select Abarth in Col G, I only want the 500/695 or 124 displayed in a drop down, where I will choose 124
Blockquote
Col I: Similar to Col H, now only Abarth 124 related items should be displayed in the drop down

SOLVED! I have written macros to resolve as follows:
Sub SelectModel()
'
' SelecModel Macro
'
'
ActiveCell.Select
' Save the active cell to use later
Set myActiveCell = ActiveCell
Set myActiveWorksheet = ActiveSheet
Set myActiveWorkbook = ActiveWorkbook
ActiveCell.Copy Destination:=Sheets("2018MMCodes").Range("AU1")
Sheets("2018MMCodes").Select
If (ActiveSheet.AutoFilterMode And ActiveSheet.FilterMode) Or ActiveSheet.FilterMode Then
ActiveSheet.ShowAllData
End If
Columns("AV:AX").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Selections").Select
Range("A1").Select
ActiveSheet.Paste
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
ActiveSheet.Range("$A$1:$C$3257").RemoveDuplicates Columns:=2, Header:= _
xlYes
'Returns the user to the original sheet to enable just making a selection
myActiveWorkbook.Activate
myActiveWorksheet.Activate
myActiveCell.Activate
End Sub
Sub SelectVariant()
'
' SelectVariant Macro
'
'
ActiveCell.Select
' Save the active cell to use later
Set myActiveCell = ActiveCell
Set myActiveWorksheet = ActiveSheet
Set myActiveWorkbook = ActiveWorkbook
Selection.Copy
Sheets("2018MMCodes").Select
Range("AU3").Select
ActiveSheet.Paste
Columns("AV:AX").Select
Application.CutCopyMode = False
Application.CutCopyMode = False
Application.CutCopyMode = False
Application.CutCopyMode = False
Range("AV1:AX3257").AdvancedFilter Action:=xlFilterInPlace, CriteriaRange:= _
Range("'2018MMCodes'!Criteria"), Unique:=False
Selection.Copy
Sheets("Selections").Select
Range("A1").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
'Returns the user to the original sheet to enable just making a selection
myActiveWorkbook.Activate
myActiveWorksheet.Activate
myActiveCell.Activate
End Sub

Related

looking to loop through a table and return values from first and second column along with eighth and ninth column to a different sheet

The title says most of it what I am looking to create is an inventory management system to handle the inventory for my area but I keep getting runtime errors in my code, I am not super proficient at VBA but I have a base knowledge. Code I am working on is below, any help would be awesome.
Edit:
Specific runtime error is 1004: Select Method of Range class failed on line 15 after is has already copy and pasted one.
Sub add2Order()
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
Application.ScreenUpdating = False
Dim C As range, Rng As range, D As range, Rng1 As range
Set Rng = range("K6", range("K6").End(xlDown))
For Each C In Rng
If InStr(1, C, "X") > 0 Then
'first select material number and name
range(C.Offset(0, -9), C.Offset(0, -8)).Select
Application.CutCopyMode = False
Selection.Copy
'paste in reorder sheet
Sheets("Re-Order List").Select
Selection.End(xlDown).Select
range("A65536").Select
Selection.End(xlUp).Offset(1, 0).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = True
End If
Next
Set Rng1 = range("K6", range("K6").End(xlDown))
For Each D In Rng1
If InStr(1, D, "X") > 0 Then
'Second select amount and cost
range(D.Offset(0, -2), D.Offset(0, -1)).Select
Application.CutCopyMode = False
Selection.Copy
'paste in reorder sheet
Sheets("Re-Order List").Select
Selection.End(xlDown).Select
range("C65536").Select
Selection.End(xlUp).Offset(1, 0).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = True
End If
Next
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
Inventory sheet to copy from
Reorder sheet to paste in
If you remove "select" your macro should look like this:
Sub add2Order()
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
Application.ScreenUpdating = False
Dim C As Range, Rng As Range, D As Range, Rng1 As Range
Set Rng = Range("K6", Range("K6").End(xlDown))
For Each C In Rng
If InStr(1, C, "X") > 0 Then
'first select material number and name
Application.CutCopyMode = False
Range(C.Offset(0, -9), C.Offset(0, -8)).Copy
'paste in reorder sheet
Sheets("Re-Order List").Range("A65536").End(xlUp).Offset(1, 0).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = True
End If
Next
Set Rng1 = Range("K6", Range("K6").End(xlDown))
For Each D In Rng1
If InStr(1, D, "X") > 0 Then
'Second select amount and cost
Application.CutCopyMode = False
Range(D.Offset(0, -2), D.Offset(0, -1)).Copy
'paste in reorder sheet
Sheets("Re-Order List").Range("C65536").End(xlUp).Offset(1, 0).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = True
End If
Next
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
If you run a macro on sheets (1) and You do "select" or "active" sheets (2) in your code, excel has a problem because both sheets are therefore indicated as active.

Remove duplicates but choose the old data to delete

I have this procedure that I have copied from a couple of forums and adapted to my needs. The procedure removes duplicates perfectly than copies my formatting as needed.
However, it is removing the new records that are duplicates and leaving me the old date.
I have a sheet with rows of data for loans and their statuses. The statuses change everyday and so I copy the new data to the next available row and then run the procedure. The procedure is leaving the old date and removing the new data as the duplicate. How can I modify so that it recognizes that the new pasted data are the duplicated records I want to keep and removes the old date as the duplicates?
Sub RemoveDuplicateRows()
'Demonstrates how to use the VBA RemoveDuplicates method to remove
'the duplicate rows from a particular column in a range of data.
Dim MyRange As Range
Dim LastRow As Long
LastRow = ActiveSheet.Range("B" & Rows.Count).End(xlUp).Row
Set MyRange = ActiveSheet.Range("A11:T" & LastRow)
MyRange.RemoveDuplicates Columns:=2, Header:=xlYes
Range("A11:T1000" & LastRow).Select
Selection.Copy
'pastes range with duplicates removed
Range("A11:T1000").Select
Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Application.CutCopyMode = False
Range("A11:T11").Select
Selection.Copy
'Copies formatiing
Range("A12:T1000").Select
Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Application.CutCopyMode = False
ActiveWindow.SmallScroll Down:=24
GoToEnd
End Sub
I was able to resolve by Tim Williams' suggestion to sort data in such a way that I had to get the new data above the old data. I accomplished this by using a helper column to timestamp the data.
I am not an expert (at all) so I am sure it can be written much more efficiently, but here is the full code for anyone seeking this topic:
Sub RemoveDuplicateRows()
'Demonstrates how to use the VBA RemoveDuplicates method to remove
'the duplicate rows from a particular column in a range of data.
Dim MyRange As Range
Dim LastRow As Long
ActiveSheet.Unprotect
Application.EnableEvents = False
Dim r As Range
Set r = ActiveSheet.Range("$a$10:$u$1000")
If (ActiveSheet.AutoFilterMode And ActiveSheet.FilterMode) Or ActiveSheet.FilterMode
Then
ActiveSheet.ShowAllData
End If
Range("a11:u1000").Select
Selection.Sort Key1:=Range("U11"), Order1:=xlDescending, Key2:=Range("B11") _
, Order2:=xlAscending, Header:=xlYes, OrderCustom:=1, MatchCase:= _
False, Orientation:=xlTopToBottom
LastRow = ActiveSheet.Range("B" & Rows.Count).End(xlUp).Row
Set MyRange = ActiveSheet.Range("A11:U" & LastRow)
MyRange.RemoveDuplicates Columns:=2, Header:=xlYes
Range("A11:U" & LastRow).Select
Selection.Copy
'pastes range with duplicates removed
Range("A11:U1000").Select
Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Application.CutCopyMode = False
Range("A11:U11").Select
Selection.Copy
'Copies formatiing
Range("A12:U1000").Select
Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Application.CutCopyMode = False
ActiveWindow.SmallScroll Down:=24
GoToEnd
Application.EnableEvents = True
End Sub

How to repeat code to apply merged cell formatting to multiple rows?

I'm creating a button that will allow the user to add a new record to the very top of the list, and move all records one row below (to keep the newest records at the top). The code I've written works perfectly as-is. However, I have to write a lot of repeating code to apply it to all rows within the range. Here is my code:
Sub Test2()
' Stop screen from following macro actions & disable alerts
Application.ScreenUpdating = False
Application.DisplayAlerts = False
' If more than 1 record, copy all rows and paste 1 row below, apply merged cell formatting, clear data from first row, and re-enable alerts/screen updating
If WorksheetFunction.CountA(Range("AM5:AN21")) > 1 Then
Range("CW28:DJ28").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Range("CW29:DJ29").Select
ActiveSheet.Paste
Range("CW28:DJ28").Select
Selection.Copy
Range("CW29").Select
Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
...
Range("CW1277").Select
Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Application.CutCopyMode = False
Range("CW28:DJ28").Select
Selection.ClearContents
Range("CW28:CX28").Select
Application.DisplayAlerts = True
Application.ScreenUpdating = True
' If only 1 record, copy first row and paste 1 row below, apply merged cell formatting, clear data from first row, and re-enable alerts/screen updating
ElseIf WorksheetFunction.CountA(Range("AM5:AN21")) = 1 Then
Range("CW28:DJ28").Select
Selection.Copy
Range("CW29:DJ29").Select
ActiveSheet.Paste
Range("CW28:DJ28").Select
Selection.Copy
Range("CW29").Select
Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
...
Range("CW1277").Select
Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Application.CutCopyMode = False
Range("CW28:DJ28").Select
Selection.ClearContents
Range("CW28:CX28").Select
Application.DisplayAlerts = True
Application.ScreenUpdating = True
' If zero records, re-enable alerts/screen updating
Else
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End If
End Sub
As you can see, the two spots where the "..." I need to apply to rows 29 through 1277. I know there's got to be a better way to do this with For ... Next, but what I've tried hasn't worked (code that I used is below, it would give me an error saying I can't do that to merged cells, even though my current code works).
Dim rng As Range: Set rng = Application.Range("CW28:CX1277")
Dim i As Integer
For i = 1 To 1248
rng.Cells(RowIndex:=i, ColumnIndex:="CW").Select
Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Next
I know my entire issue is that we have merged cells, but we need to keep them if at all possible. Knowing that my current, repetitive coding works... is there a way to make the For ... Next function work?
What I understand of your code is that you copy the format of line N to line N+1 for columns CW to DJ, from lines 28 to 1277, by block.
(I strongly suppose it is not as much simple).
What you could do is (I replace your 28 by beginRow) :
dim beginRow as long, endRow as long
dim strRange as string
beginRow=28
while (beginRow<<1277)
strRange = "CW" & beginRow & ":DJ" & beginRow
Range(strRange).select
endRow=Selection.End(xlDown).row
strRange = "CW" & beginRow & ":DJ" & endRow
Range(strRange).Copy
strRange = "CW" & (beginRow+1) & ":DJ" & (endRow+1)
Range(strRange).Select
ActiveSheet.Paste
strRange = "CW" & (beginRow) & ":DJ" & (beginRow+1)
Range(strRange).Copy
Range("CW" & (beginRow+1)).Select
Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
' find next block
beginRow=Range("CW" & (endRow+1)).End(xlDown).row
wend
Could this help ?
Pierre.
I figured it out!
Dim rng As Range
Dim cell As Range
Range("CW28:DJ28").Select
Selection.Copy
Set rng = Range("CW29:1277")
For Each cell In rng.Cells
cell.Select
Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Next cell
Application.CutCopyMode = False
Now, I need to focus on how to get rid of .Select and .Activate throughout my code. Thank you so much for your help, all!

Loop that references different sheet names each iteration

I have the following loop to create multiple tabs in Excel 2016 based on a list of PO#'s. ( see code below)
Sub CreateSheetsFromAList()
Dim MyRange As Range
Dim dic As Object, c As Range
Dim k As Variant, tmp As String
Set dic = CreateObject("scripting.dictionary")
Set MyRange = Sheets("Instructions").Range("h6")
Set MyRange = Range(MyRange, MyRange.End(xlDown))
Sheets("Template").Visible = True
For Each c In MyRange
tmp = Trim(c.Value)
If Len(tmp) > 0 Then dic(tmp) = dic(tmp) + 1
Next c
For Each k In dic.keys
If Not WorksheetExists(k) Then
Sheets("Template").Copy After:=Sheets(Sheets.Count)
ActiveSheet.Name = k
End If
Next k
End Sub
Public Function WorksheetExists(ByVal WorksheetName As String) As Boolean
On Error Resume Next
WorksheetExists = (Sheets(WorksheetName).Name <> "")
On Error GoTo 0
End Function
I also need to populate each newly created tab with info from another workbook (EDI PO Consolidated - 2018.xlsx)
(see code below)
Sub BandB2()
' BandB2 Macro
' Keyboard Shortcut: Ctrl+b
'
Application.Goto Reference:="R20C10"
Selection.Copy
Windows("EDI PO Consolidated - 2018.xlsx").Activate
ActiveSheet.Range("$A$1:$X$2628").AutoFilter Field:=2, Criteria1:= _
"34535453"
Application.Goto Reference:="R1C9"
Range("I2058").Select
Application.CutCopyMode = False
Selection.Copy
Windows("Book and Bill form - template.xlsm").Activate
Range("J26").Select
ActiveSheet.Paste
Windows("EDI PO Consolidated - 2018.xlsx").Activate
ActiveWindow.SmallScroll ToRight:=4
Application.Goto Reference:="R1C17"
Range("Q2058").Select
Range(Selection, Selection.End(xlDown)).Select
Application.CutCopyMode = False
Selection.Copy
Windows("Book and Bill form - template.xlsm").Activate
ActiveWindow.SmallScroll Down:=6
Range("C33").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Windows("EDI PO Consolidated - 2018.xlsx").Activate
Application.Goto Reference:="R1C14"
Range("N2058").Select
Range(Selection, Selection.End(xlDown)).Select
Application.CutCopyMode = False
Selection.Copy
Windows("Book and Bill form - template.xlsm").Activate
Range("D33").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Windows("EDI PO Consolidated - 2018.xlsx").Activate
Application.Goto Reference:="R1C18"
Range("R2058:T2058").Select
Range(Selection, Selection.End(xlDown)).Select
Application.CutCopyMode = False
Selection.Copy
Windows("Book and Bill form - template.xlsm").Activate
Range("E33").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End Sub
I have 2 questions:
1) i cannot make the sheet reference change for each tab; it always picks the
1st po# "34535453"
2) Can you help me combine these into 1 macro.
thank you in advance for your help
Here's a cleaner way to create those tabs.
Name cell H6 on the Instructions tab "PO_Start" or some other appropriate name. That way if you can insert rows or columns on the tab without possibly having to change the reference to H6 in your code.
Sub Create_Sheets()
Dim PO_list, PO As Range
Set PO_list = Range(Sheets("Instructions").Range("PO_Start"), Sheets("Instructions").Range("PO_Start").End(xlDown))
Sheets("Template").Visible = True
For Each PO In PO_list
If Not WorksheetExists(PO) Then
Sheets("Template").Copy After:=Sheets(Sheets.Count)
ActiveSheet.Name = PO
End If
Next PO
End Sub
1) To loop through your tabs, if you know that your PO tabs will always start on tab 3, you can loop through the sheets like this (including variable declarations):
Sub B_and_B()
Dim ws As Worksheet
Dim i As Integer
For i = 3 To Sheets.Count
Set ws = Sheets(i)
'... rest of code here
Next i
End Sub
Otherwise if down the road you anticipate adding other sheets besides "Instructions" and "Template" to your Book and Bill file, you could loop through all sheets, error checking to see if you can convert the sheet name to a "long" variable type with Clng(). Probably more than what's needed for your current project.
Another tip:
Avoid using hard-coded cell addresses ("N2058") in your code. If you filter on purchase orders in the Consolidated book and then pull in certain data elements, you'll need to find the row the Purchase Order is in (2058 in this case).
2) To combine these into one macro, you can create a Main subroutine, calling each step separately:
Sub Main()
Call Create_Sheets
Call B_and_B
End Sub

insert formula in column until next non blank cell

In my macro, i need to insert a formula in columns AA and AB, AB is empty so no problem there. Column AA has data which starts in AA10954, my problem is AA10954 changes each week as my data either increases or decrease as i import from another book, can someone help me to set the last empty cell before my data starts in AA?
Sub ClassVisit()
'
' ClassVisit Macro
'
'
Dim lr As Long
With ActiveWorkbook
With ActiveSheet
lr = .Cells(.Rows.Count, "A").End(xlUp).Row
Range("AA2").Formula = "=IFERROR(VLOOKUP(A2,[Data.xlsb]Stores!$A:$AA,27,0),VLOOKUP(A2,'[Salesinfo.xlsb]Packs'!$C:$E,3,0))"
Range("AB2:AB" & lr).Formula = "=IFERROR(VLOOKUP(A2,Attribute!D:F,3,0),""Not Visited"")"
Range("AA2").Select
Selection.AutoFill Destination:=ActiveCell.Range("A1:A10953")
ActiveCell.Range("A1:A10953").Select
Range("AA2:AB" & lr).Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Selection.End(xlUp).Select
Application.CutCopyMode = False
ActiveCell.Offset(1, -26).Range("A1").Select
End With
End With
End Sub

Resources