Home > Net >  how to create a dropdown list in multiple excel sheets from data of one sheet
how to create a dropdown list in multiple excel sheets from data of one sheet

Time:03-09

This is a tough task that I must complete for a collegue project. I'm not an expert doing vba macros but trying my best so far so lets start the explanation:

First, I have multiples sheets (around 300) that are called by Matrix and followed by a number from 1 to 330, e.g: Matrix1,Matrix2, etc., each of these sheets contains multiple product attributes that are positioned in row 1 as can be seen in the next screenshot: enter image description here

what I need to do is that every time a product attribute that contains the phrase: "Select from dropdown list" in row number 2, automatically generate a dropdown list in the same column, from row 3 to row 100. The values that should be in the generated dropdown list come from the "Dropdown" sheet as shown below: enter image description here

As can be seen, a product attribute contains a long list of values and would need those values to be displayed in the dropdown list according to the attribute that corresponds to it. This should happen for each of the matrix sheets that the excel has.

this is the code that previously helped me for a past task, but this one requires more extensive coding:

Option Explicit

Sub MultiDataValidation()
    
    Const sName As String = "Sheet1"
    Const scCol As String = "A"
    Const svCol As String = "B"
    Const sfRow As Long = 6
    
    Const dName As String = "Sheet1"
    Const dcAddress As String = "G2:I2"
    Const dvRow As Long = 3
    
    Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
    
    Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
    Dim slRow As Long: slRow = sws.Cells(sws.Rows.Count, svCol).End(xlUp).Row
    If slRow < sfRow Then Exit Sub ' no data
    Dim srCount As Long: srCount = slRow - sfRow   1
    Dim scrg As Range: Set scrg = sws.Cells(sfRow, scCol).Resize(srCount)
    
    Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
    Dim dcrg As Range: Set dcrg = dws.Range(dcAddress)
    
    Dim srg As Range
    Dim sCell As Range
    Dim srIndex As Variant
    Dim dCell As Range
    
    For Each dCell In dcrg.Cells
        srIndex = Application.Match(dCell.Value, scrg, 0)
        If IsNumeric(srIndex) Then
            Set sCell = scrg.Cells(srIndex)
            If sCell.MergeCells Then
                Set srg = sCell.MergeArea
            Else
                Set srg = sCell
            End If
            With dCell.EntireColumn.Rows(dvRow).Validation
                .Delete
                .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, _
                    Formula1:="=" & srg.EntireRow.Columns(svCol).Address
                .IgnoreBlank = True
                .InCellDropdown = True
                .InputTitle = ""
                .ErrorTitle = ""
                .InputMessage = ""
                .ErrorMessage = ""
                .ShowInput = True
                .ShowError = True
            End With
        End If
    Next dCell
    
End Sub

CodePudding user response:

Distribute Dropdowns

Option Explicit

Sub DistributeDropdowns()
    Const ProcName As String = "DistributeDropdowns"
    On Error GoTo ClearError

    Const sName As String = "Dropdown"
    Const saCol As Long = 1
    Const svCol As Long = 2
    
    Const dNameLeft As String = "Matrix"
    Const ddIdentifier As String = "Select from the dropdown list."
    Const dvRows As String = "3:100"

    Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
    
    Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
    Dim srg As Range: Set srg = sws.Range("A1").CurrentRegion.Columns(saCol)

    Dim nCount As Long: nCount = srg.Rows.Count
    Dim nData As Variant: nData = srg.Value
    
    Dim dict As Object: Set dict = CreateObject("Scripting.Dictionary")
    dict.CompareMode = vbTextCompare
    
    Dim n As Long
    Dim nString As String
    
    For n = 2 To nCount
        nString = nData(n, 1)
        If dict.Exists(nString) Then
            Set dict(nString) = Union(dict(nString), sws.Cells(n, svCol))
        Else
            Set dict(nString) = sws.Cells(n, svCol)
        End If
    Next n
        
    Dim dLen As Long: dLen = Len(dNameLeft)

    Application.ScreenUpdating = False

    Dim dws As Worksheet
    Dim drg As Range
    
    For Each dws In wb.Worksheets
        If Left(dws.Name, dLen) = dNameLeft Then
            With dws.Range("A1").CurrentRegion.Resize(2)
                nCount = .Columns.Count
                nData = .Value
                Set drg = .EntireColumn.Rows(dvRows)
            End With
            For n = 2 To nCount
                If nData(2, n) = ddIdentifier Then
                    If dict.Exists(nData(1, n)) Then
                        With drg.Columns(n).Validation
                            .Delete
                            .Add xlValidateList, xlValidAlertStop, xlEqual, _
                                "='" & sName & "'!" & dict(nData(1, n)).Address
                            .IgnoreBlank = True
                            .InCellDropdown = True
                            .InputTitle = ""
                            .ErrorTitle = ""
                            .InputMessage = ""
                            .ErrorMessage = ""
                            .ShowInput = True
                            .ShowError = True
                        End With
                    End If
                End If
            Next n
        End If
    Next dws
    
    'wb.Save
    
    Application.ScreenUpdating = True
    MsgBox "Dropdowns distributed.", vbInformation

ProcExit:
    Exit Sub
ClearError:
    Debug.Print "'" & ProcName & "' Run-time error '" _
        & Err.Number & "':" & vbLf & "    " & Err.Description
    Resume ProcExit
End Sub
  • Related