UserForm to Search Workbook

BrendanDixon

Board Regular
Joined
Mar 7, 2010
Messages
174
Office Version
  1. 365
  2. 2019
Platform
  1. Windows
Hi All,

I have a userform called "Search" I have a textbox called "TextBox1"
and a button called "CommandButton1" I would like to have some programming that what ever I type in the text box and then press the button it will go to the cell with with the same text. while keeping the userform on top. if I click on the button again it will go to the next value of the text in the text box. My workbook has multiple sheets and I want the search to ignore Case differences.

Does anyone know how to do this and could you please help me. I do not know where to start with this.
 
Hey Alan, that's nice functionality! Thank you very much. I like the live results. How do I get the column headers for 'Organisation Name', 'Individual Name', 'Telephone Number' etc (the column headers listed in the worksheets) to all show in the results?

Code:
Option ExplicitDim iPtr As Integer
Dim mrCurrentCell As Range
Dim msaWorksheets() As String, msFirstAddress As String
Dim objCtrl As Control
Dim cNum As Integer, x As Integer, i As Integer
Dim nextrow As Long
Dim AlignLeft As Boolean


Private Sub UserForm_Initialize()
CheckSize
ReDim msaWorksheets(1 To ThisWorkbook.Sheets.Count)
For iPtr = 1 To UBound(msaWorksheets)
    msaWorksheets(iPtr) = ThisWorkbook.Sheets(iPtr).Name
Next iPtr
Set mrCurrentCell = Nothing
lblresults.Caption = ""
With lbs
    cbContactType.List = Array("Council Contacts", "Local Contacts", "Housing Associations", "Landlords", "Letting and Selling Agents", "Developers", "Employers")
    lblOrganisationName.Visible = False
        txt1.Visible = False
    lblContactName.Visible = False
        txt2.Visible = False
    lblTelephoneNumber.Visible = False
        txt3.Visible = False
    lblEmailAddress.Visible = False
       txt4.Visible = False
    lblPostalAddress.Visible = False
      txt5.Visible = False
    lblPassword.Visible = False
        txt6.Visible = False
    cmdbReset.Enabled = False
    cmdbUpdate.Enabled = False
    cmdbNew.Enabled = False
    cmdbChange.Enabled = False
    cmdbDelete.Enabled = False
    MLA.Visible = False
    mstrAccounts.Visible = False
    mstrNo.Value = True
        txt7.Visible = False
    lbs.Visible = False
    lbs.ColumnCount = 7
    lbs.ColumnHeads = True
    lbs.ColumnWidths = "135 pt;142 pt;135 pt;135 pt;135 pt;135 pt;135 pt;135 pt"
    lb.Visible = False
    lb.ColumnCount = 7
    lb.ColumnHeads = True
    lb.ColumnWidths = "135 pt;142 pt;135 pt;135 pt;135 pt;135 pt;135 pt;135 pt"
        For Each objCtrl In Me.Controls
            If Left(objCtrl.Name, 4) = "Text" Then txt7.Visible = False
        Next
        If txt7.Value = "" Then
            txt7.Value = "Example1: " & vbCrLf & "Example2: " & vbCrLf & "Example3: "
        End If
End With
End Sub


Private Sub CheckSize()
Dim h, w
Dim c As Control
    h = 0: w = 0
    For Each c In Me.Controls
        If c.Visible Then
            If c.Top + c.Height > h Then h = c.Top + c.Height
            If c.Left + c.Width > w Then w = c.Left + c.Width
        End If
    Next c


    If h > 0 And w > 0 Then
        With Me
            .Width = w + 10
            .Height = h + 10
        End With
    End If
End Sub


Private Sub iptSearch_Change()
Dim lPointer As Long
Dim lStartPointer As Long
Dim lFoundCount As Long


Dim sCurName As String
Dim sCurrentFoundAddress As String


Dim vaResults As Variant


Dim WS As Worksheet


Set mrCurrentCell = Nothing
lStartPointer = 1


With lbs
    .Clear
    .ColumnCount = 7
    .ColumnHeads = False
End With


lblresults.Caption = ""
lFoundCount = -1


If iptSearch.Text <> "" Then
    ReDim vaResults(0 To 1, 0 To 0)
    
    For lPointer = lStartPointer To UBound(msaWorksheets)
        msFirstAddress = ""
        Set WS = Sheets(msaWorksheets(lPointer))
        Set mrCurrentCell = WS.Cells.Find(what:=iptSearch.Value, LookIn:=xlValues, lookat:=xlPart)
        Do While Not (mrCurrentCell Is Nothing)
            sCurrentFoundAddress = WS.Name & "!" & mrCurrentCell.Address(False, False)
            If sCurrentFoundAddress = msFirstAddress Then Exit Do
            If msFirstAddress = "" Then msFirstAddress = sCurrentFoundAddress
            lFoundCount = lFoundCount + 1
            ReDim Preserve vaResults(0 To 1, 0 To lFoundCount)
            vaResults(0, lFoundCount) = sCurrentFoundAddress
            vaResults(1, lFoundCount) = mrCurrentCell.Value
            Set mrCurrentCell = WS.Cells.FindNext(mrCurrentCell)
        Loop
    Next lPointer
    If lFoundCount > -1 Then
        If lFoundCount = 0 Then
            With lbs
                .Clear
                .ColumnCount = 7
                .AddItem
                .Column(0, 0) = vaResults(0, 0)
                .Column(1, 0) = vaResults(1, 0)
            End With
    '        lbs.List = vaResults
            lblresults.Caption = "1 result found"
        Else
            lbs.List = WorksheetFunction.Transpose(vaResults)
            lblresults.Caption = lFoundCount + 1 & " results found"
        End If
    Else
        lblresults.Caption = "No results found"
    End If
End If


lbs.Visible = lFoundCount > -1
End Sub


Private Sub cbContactType_Change()
    cmdbNew.Enabled = CBool(cbContactType.ListIndex <> -1)
    mstrNo.Value = True
    If cbContactType.Enabled Then Set WS = Worksheets(cbContactType.Text)
    
    If cbContactType.Value = "Housing Associations" Or _
       cbContactType.Value = "Landlords" Then
       mstrAccounts.Visible = True
       MLA.Visible = True
    Else
        mstrAccounts.Visible = False
        MLA.Visible = False
    End If
    
    lastRow = WS.Range("B" & Rows.Count).End(xlUp).Row
    CurrentRow = lastRow + 1
    
    'loop thru and clear textboxes
    For i = 1 To 6
        Contacts.Controls("txt" & i).Value = ""
        Contacts.Controls("txt" & i).BackColor = vbWhite
        Contacts.Controls("txt" & i).ForeColor = vbBlack
        Contacts.Controls("txt" & i).Visible = True
    Next i
    
    Contacts.dtaRow.Caption = lastRow - 1 & " Record"
    
    lblOrganisationName.Visible = True
    lblContactName.Visible = True
    lblTelephoneNumber.Visible = True
    lblEmailAddress.Visible = True
    lblPostalAddress.Visible = True
    lblPassword.Visible = True
    cmdbReset.Enabled = True
    cmdbChange.Enabled = True
    cmdbDelete.Enabled = True
    lb.Visible = True
    WS.Activate
    lb.RowSource = "B2:H" & lastRow
End Sub


Private Sub cmdbChange_SpinUp()
    If CurrentRow < lastRow Then
        CurrentRow = CurrentRow + 1
        UpdatecmdbChange
    Else
        CurrentRow = 2
        UpdatecmdbChange
    End If
    lb.ListIndex = CurrentRow - 2
End Sub


Private Sub cmdbChange_SpinDown()
    If CurrentRow > 2 Then
        CurrentRow = CurrentRow - 1
        UpdatecmdbChange
    Else
        CurrentRow = lastRow
        UpdatecmdbChange
    End If
    lb.ListIndex = CurrentRow - 2
End Sub


Private Sub cmdbReset_Click()
    Application.ScreenUpdating = False
    Unload Me
    Contacts.Show
    Application.ScreenUpdating = True
End Sub


Private Sub txt1_AfterUpdate()
    If Len(txt1) > 3 Then cmdbUpdate.Enabled = True
End Sub


Private Sub txt2_AfterUpdate()
    If Len(txt2) > 3 Then cmdbUpdate.Enabled = True
End Sub


Private Sub txt3_AfterUpdate()
    If Len(txt3) > 3 Then cmdbUpdate.Enabled = True
End Sub


Private Sub txt4_AfterUpdate()
    If Len(txt4) > 3 Then cmdbUpdate.Enabled = True
End Sub


Private Sub txt5_AfterUpdate()
    If Len(txt5) > 3 Then cmdbUpdate.Enabled = True
End Sub


Private Sub txt6_AfterUpdate()
    If Len(txt6) > 3 Then cmdbUpdate.Enabled = True
End Sub


Private Sub cmdbUpdate_Click()
    
    If txt1.Value = "" And txt2.Value = "" And txt3.Value = "" _
        And txt4.Value = "" And txt5.Value = "" And txt6.Value = "" Then
        MsgBox "Please update data in at least one text box.", 48, "Error"
        Exit Sub
    End If
    
    With Application
        .Calculation = xlCalculationManual
        .ScreenUpdating = False
        .DisplayStatusBar = False
        .EnableEvents = False
    End With
    
    If txt7.Visible = True Then
        cNum = 7
    Else
        cNum = 6
    End If
        
    For x = 1 To cNum
        'AlignLeft = CBool(x = 1 Or x = 7)
        With WS.Cells(CurrentRow, x + 1)
            .Value = Me.Controls("txt" & x).Value
        End With
    Next
    With Application
        .Calculation = xlCalculationAutomatic
        .ScreenUpdating = True
        .DisplayStatusBar = True
        .EnableEvents = True
    End With
    
    MsgBox "Contact modified in " & WS.Name, 64, "Success"
End Sub


Private Sub cmdbNew_Click()
    If txt1.Value = "" And txt2.Value = "" And txt3.Value = "" _
        And txt4.Value = "" And txt5.Value = "" And txt6.Value = "" Then
        MsgBox "Please enter data into at least one field.", 48, "Error"
        Exit Sub
    End If
    nextrow = WS.Cells(WS.Rows.Count, "B").End(xlUp).Row
    If Len(WS.Cells(1, 2).Value) > 0 Then nextrow = nextrow + 1
        If txt7.Visible = True Then
            cNum = 7
        Else
            cNum = 6
        End If
    For x = 1 To cNum
        AlignLeft = CBool(x = 1 Or x = 7)
        With WS.Cells(nextrow, x + 1)
            .Value = Me.Controls("txt" & x).Value
            .EntireColumn.AutoFit
            .HorizontalAlignment = IIf(x = 1 Or x = 7, xlLeft, xlCenter)
            .VerticalAlignment = xlCenter
                With .Font
                     .Name = "Arial"
                     .FontStyle = "Regular"
                     .Size = 10
                End With
        End With
        Controls("txt" & x).Text = ""
    Next
    MsgBox "Contact added to " & WS.Name, 64, "Success"
    Application.ScreenUpdating = False
    Unload Me
    Contacts.Show
    Application.ScreenUpdating = True
End Sub


Private Sub cmdbDelete_Click()
Dim smessage As String
    smessage = "Are you sure you want to delete this contact?" & vbCrLf & vbCrLf & "Name: " & txt2.Text & vbCrLf & "From: " & txt1.Text
    
    If MsgBox(smessage, vbQuestion & vbYesNo, _
              "Delete") = vbYes Then
    WS.Rows(CurrentRow).Delete
    End If
    lastRow = lastRow - 1
    lb.RowSource = "B2:H" & lastRow
End Sub


Private Sub cmdbClose_Click()
Unload Me
End Sub


Private Sub mstrYes_Click()
    txt7.Visible = True
End Sub


Private Sub mstrNo_Click()
    txt7.Visible = False
End Sub


Private Sub lb_Click()
    CurrentRow = lb.ListIndex + 2
    UpdatecmdbChange
End Sub

afaik, the only way to achieve this is to store the results into a worksheet and point the listbox at that.
Anyone else know how to do this without storing first?
 
Upvote 0

Excel Facts

How can you automate Excel?
Press Alt+F11 from Windows Excel to open the Visual Basic for Applications (VBA) editor.
Whilst we deliberate on that point, can we show the results from the other columns of data, without the column headings? Instead of two columns, there should be seven covering the data I described previously.
 
Upvote 0
Couldn't see your previously described data, but cribbing from your existing code, try this code, which creates (if necessary) a worksheet "SearchResults" but keeps it hidden to hold the data for the Listbox:
Code:
Option Explicit
Dim AlignLeft As Boolean

Dim objCtrl As Control

Dim iPtr As Integer
Dim cNum As Integer
Dim x As Integer
Dim i As Integer

Dim mrCurrentCell As Range

Dim msaWorksheets() As String
Dim msFirstAddress As String

Dim NextRow As Long

Dim mvaSearchResults() As Variant
Dim mvaSearchHeadings() As Variant

Dim mwsSearchResults As Worksheet

Private Sub UserForm_Initialize()
Dim lWSPtr As Long
Dim lWSCount As Long
Dim sCurWS As String

CheckSize

lWSCount = 0
ReDim msaWorksheets(1 To 1)
For lWSPtr = 1 To ThisWorkbook.Sheets.Count
    sCurWS = ThisWorkbook.Sheets(lWSPtr).Name
    If sCurWS <> "Search" And sCurWS <> "SearchResults" Then
        lWSCount = lWSCount + 1
        ReDim Preserve msaWorksheets(1 To lWSCount)
        msaWorksheets(lWSCount) = sCurWS
    End If
Next lWSPtr

Set mrCurrentCell = Nothing
btnSearch.Enabled = False
lblresults.Caption = ""
With lbs
    cbContactType.List = Array("Council Contacts", "Local Contacts", "Housing Associations", "Landlords", "Letting and Selling Agents", "Developers", "Employers")
    lblOrganisationName.Visible = False
        txt1.Visible = False
    lblContactName.Visible = False
        txt2.Visible = False
    lblTelephoneNumber.Visible = False
        txt3.Visible = False
    lblEmailAddress.Visible = False
       txt4.Visible = False
    lblPostalAddress.Visible = False
      txt5.Visible = False
    lblPassword.Visible = False
        txt6.Visible = False
    cmdbReset.Enabled = False
    cmdbUpdate.Enabled = False
    cmdbNew.Enabled = False
    cmdbChange.Enabled = False
    cmdbDelete.Enabled = False
    MLA.Visible = False
    mstrAccounts.Visible = False
    mstrNo.Value = True
        txt7.Visible = False
    lbs.Visible = False
'    lbs.ColumnCount = 7
    lbs.ColumnCount = 8
    lbs.ColumnHeads = True
    lbs.ColumnWidths = "135 pt;142 pt;135 pt;135 pt;135 pt;135 pt;135 pt;135 pt"
    lb.Visible = False
    lb.ColumnCount = 7
    lb.ColumnHeads = True
    lb.ColumnWidths = "135 pt;142 pt;135 pt;135 pt;135 pt;135 pt;135 pt;135 pt"
        For Each objCtrl In Me.Controls
            If Left(objCtrl.Name, 4) = "Text" Then txt7.Visible = False
        Next
        If txt7.Value = "" Then
            txt7.Value = "Example1: " & vbCrLf & "Example2: " & vbCrLf & "Example3: "
        End If
End With

'    'Create Headers
'        .Range("A1").Value = "#"
'        .Range("B1").Value = "Company Name"
'        .Range("C1").Value = "Contact Name"
'        .Range("D1").Value = "Telephone Number"
'        .Range("E1").Value = "Password"
'        .Range("F1").Value = "E-mail Address"
'        .Range("G1").Value = "Postal Address"
'        .Range("H1").Value = "Worksheet"
ReDim mvaSearchHeadings(1 To 8, 1 To 1)
mvaSearchHeadings(1, 1) = "#"
mvaSearchHeadings(2, 1) = "Company Name"
mvaSearchHeadings(3, 1) = "Contact Name"
mvaSearchHeadings(4, 1) = "Telephone Number"
mvaSearchHeadings(5, 1) = "Password"
mvaSearchHeadings(6, 1) = "E-mail Address"
mvaSearchHeadings(7, 1) = "Postal Address"
mvaSearchHeadings(8, 1) = "Worksheet"

On Error Resume Next
Set mwsSearchResults = Nothing
Set mwsSearchResults = Sheets("SearchResults")
If mwsSearchResults Is Nothing Then
    Set mwsSearchResults = Worksheets.Add(after:=ActiveSheet)
    With mwsSearchResults
        .Name = "SearchResults"
        .Visible = xlSheetHidden
    End With
End If
On Error GoTo 0
With mwsSearchResults
    .Cells.Clear
    .Range("A1").Resize(, UBound(mvaSearchHeadings, 1)).Value = WorksheetFunction.Transpose(mvaSearchHeadings)
End With
End Sub

Private Sub iptSearch_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
    If KeyCode = 13 Then
        btnSearch_Click
        End If
End Sub

Private Sub CheckSize()
Dim h, w
Dim c As Control
    h = 0: w = 0
    For Each c In Me.Controls
        If c.Visible Then
            If c.Top + c.Height > h Then h = c.Top + c.Height
            If c.Left + c.Width > w Then w = c.Left + c.Width
        End If
    Next c

    If h > 0 And w > 0 Then
        With Me
            .Width = w + 10
            .Height = h + 10
        End With
    End If
End Sub

Private Sub btnSearch_Click()
Dim ip As Integer, r As Integer
Dim sCurName As String
Dim WS As Worksheet, WSnew As Worksheet
Dim lrow As Long
    With Application
        .Calculation = xlCalculationManual
        .ScreenUpdating = False
        .DisplayStatusBar = False
        .EnableEvents = False
    End With
Worksheets.Add
Set WSnew = ActiveSheet
r = 1
For ip = 1 To UBound(msaWorksheets)
    Set WS = Sheets(msaWorksheets(ip))
    Set mrCurrentCell = WS.Cells.Find(what:=iptSearch.Value, LookIn:=xlValues, lookat:=xlPart)
    
    If Not (mrCurrentCell Is Nothing) Then
        msFirstAddress = mrCurrentCell.Address
        Do
            r = r + 1
            Set mrCurrentCell = WS.Cells.FindNext(mrCurrentCell)
            mrCurrentCell.EntireRow.Copy
            WSnew.Paste Destination:=Cells(r, 1)
            WSnew.Cells(r, 8).Value = mrCurrentCell.Worksheet.Name
        Loop While Not mrCurrentCell Is Nothing And mrCurrentCell.Address <> msFirstAddress
    End If
Next ip
With WSnew
    If r < 2 Then
        MsgBox prompt:="Cannot find '" & iptSearch.Value & "'", _
                                        Buttons:=vbOKOnly + vbInformation, _
                                        Title:="Text not found"
    Else
    'Create Headers
        .Range("A1").Value = "#"
        .Range("B1").Value = "Company Name"
        .Range("C1").Value = "Contact Name"
        .Range("D1").Value = "Telephone Number"
        .Range("E1").Value = "Password"
        .Range("F1").Value = "E-mail Address"
        .Range("G1").Value = "Postal Address"
        .Range("H1").Value = "Worksheet"
        .Range("A2").Value = 1
            If r > 2 Then .Range("A2").AutoFill Destination:=.Range("A2:A" & r), Type:=xlLinearTrend
    'populate listbox
        With Me.lbs
            .Visible = True
            .ColumnCount = 8
            .ColumnWidths = "15 pt;142 pt;135 pt;135 pt;135 pt;135 pt;135 pt;85 pt"
            .ColumnHeads = False
            .List = WSnew.Range("A1:H" & r).Value

        End With
        
        With Application
            .Calculation = xlCalculationAutomatic
            .ScreenUpdating = True
            .DisplayStatusBar = True
            .EnableEvents = True
        End With
    End If
    Application.DisplayAlerts = False
        .Delete
    Application.DisplayAlerts = True
End With
    
End Sub

Private Sub iptSearch_Change()
Dim lPointer As Long
Dim lStartPointer As Long
Dim lPtr As Long
Dim lFoundCount As Long
Dim lColumnPointer As Long
Dim lResultsColPtr As Long

Dim rResultsRange As Range

Dim sCurName As String
Dim sCurHeading As String
Dim sCurrentFoundAddress As String

Dim vaResults As Variant
Dim vaDataLine As Variant
Dim vaHeadingLine As Variant

Dim WS As Worksheet

Set mrCurrentCell = Nothing
lStartPointer = 1

lblresults.Caption = ""
lFoundCount = -1

If iptSearch.Text <> "" Then
'    ReDim vaResults(0 To 1, 0 To 0)
    ReDim mvaSearchResults(1 To UBound(mvaSearchHeadings, 1), 1 To 1)
    For lPointer = lStartPointer To UBound(msaWorksheets)
        msFirstAddress = ""
        Set WS = Sheets(msaWorksheets(lPointer))
        vaHeadingLine = Intersect(WS.Rows(1), WS.UsedRange)
        For lPtr = 1 To UBound(vaHeadingLine, 2)
            vaHeadingLine(1, lPtr) = LCase$(Replace$(vaHeadingLine(1, lPtr), " ", ""))
        Next lPtr
        
        Set mrCurrentCell = WS.Cells.Find(what:=iptSearch.Value, LookIn:=xlValues, lookat:=xlPart)
        Do While Not (mrCurrentCell Is Nothing)
            sCurrentFoundAddress = WS.Name & "!" & mrCurrentCell.Address(False, False)
            If sCurrentFoundAddress = msFirstAddress Then Exit Do
            If msFirstAddress = "" Then msFirstAddress = sCurrentFoundAddress
            If mrCurrentCell.Row > 1 Then
                lFoundCount = lFoundCount + 1
                ReDim Preserve mvaSearchResults(1 To UBound(mvaSearchResults, 1), 1 To lFoundCount + 1)
                vaDataLine = Intersect(WS.Rows(mrCurrentCell.Row), WS.UsedRange)
                For lResultsColPtr = 1 To UBound(mvaSearchResults, 1)
                    sCurHeading = mvaSearchHeadings(lResultsColPtr, 1)
                    Select Case sCurHeading
                    Case "#"
                        mvaSearchResults(lResultsColPtr, lFoundCount + 1) = lFoundCount + 1
                    Case "Worksheet"
                        mvaSearchResults(lResultsColPtr, lFoundCount + 1) = WS.Name
                    Case Else
                        lColumnPointer = GetHeadingColumn(Heading:=sCurHeading, HeadingArray:=vaHeadingLine)
                        If lColumnPointer > 0 Then
                            mvaSearchResults(lResultsColPtr, lFoundCount + 1) = vaDataLine(1, lColumnPointer)
                        End If
                    End Select
                Next lResultsColPtr
            End If
            Set mrCurrentCell = WS.Cells.FindNext(mrCurrentCell)
        Loop
    Next lPointer
    If lFoundCount < 0 Then
        lblresults.Caption = "No entries found"
    Else
        Set rResultsRange = mwsSearchResults.Range("A2").Resize(UBound(mvaSearchResults, 2), _
                                                                UBound(mvaSearchResults, 1))
        rResultsRange.Value = WorksheetFunction.Transpose(mvaSearchResults)
        lbs.RowSource = mwsSearchResults.Name & "!" & rResultsRange.Address
        
        lblresults.Caption = lFoundCount + 1 & " entries found"
            
    End If
End If

lbs.Visible = lFoundCount > -1
End Sub

Private Function GetHeadingColumn(ByVal Heading As String, ByVal HeadingArray As Variant) As Long
Dim lPtr As Long

Heading = LCase$(Replace(Heading, " ", ""))
GetHeadingColumn = 0
For lPtr = 1 To UBound(HeadingArray, 2)
    If Heading = LCase$(HeadingArray(1, lPtr)) Then
        GetHeadingColumn = lPtr
        Exit For
    End If
Next lPtr
End Function
Private Sub cbContactType_Change()
    cmdbNew.Enabled = CBool(cbContactType.ListIndex <> -1)
    mstrNo.Value = True
    If cbContactType.Enabled Then Set WS = Worksheets(cbContactType.Text)
    
    If cbContactType.Value = "Housing Associations" Or _
       cbContactType.Value = "Landlords" Then
       mstrAccounts.Visible = True
       MLA.Visible = True
    Else
        mstrAccounts.Visible = False
        MLA.Visible = False
    End If
    
    lastRow = WS.Range("B" & Rows.Count).End(xlUp).Row
    CurrentRow = lastRow + 1
    
    'loop thru and clear textboxes
    For i = 1 To 6
        Contacts.Controls("txt" & i).Value = ""
        Contacts.Controls("txt" & i).BackColor = vbWhite
        Contacts.Controls("txt" & i).ForeColor = vbBlack
        Contacts.Controls("txt" & i).Visible = True
    Next i
    
    Contacts.dtaRow.Caption = lastRow - 1 & " Record"
    
    lblOrganisationName.Visible = True
    lblContactName.Visible = True
    lblTelephoneNumber.Visible = True
    lblEmailAddress.Visible = True
    lblPostalAddress.Visible = True
    lblPassword.Visible = True
    cmdbReset.Enabled = True
    cmdbChange.Enabled = True
    cmdbDelete.Enabled = True
    lb.Visible = True
    WS.Activate
    lb.RowSource = "B2:H" & lastRow
End Sub

Private Sub cmdbChange_SpinUp()
    If CurrentRow < lastRow Then
        CurrentRow = CurrentRow + 1
        UpdatecmdbChange
    Else
        CurrentRow = 2
        UpdatecmdbChange
    End If
    lb.ListIndex = CurrentRow - 2
End Sub

Private Sub cmdbChange_SpinDown()
    If CurrentRow > 2 Then
        CurrentRow = CurrentRow - 1
        UpdatecmdbChange
    Else
        CurrentRow = lastRow
        UpdatecmdbChange
    End If
    lb.ListIndex = CurrentRow - 2
End Sub

Private Sub cmdbReset_Click()
    Application.ScreenUpdating = False
    Unload Me
    Contacts.Show
    Application.ScreenUpdating = True
End Sub

Private Sub txt1_AfterUpdate()
    If Len(txt1) > 3 Then cmdbUpdate.Enabled = True
End Sub

Private Sub txt2_AfterUpdate()
    If Len(txt2) > 3 Then cmdbUpdate.Enabled = True
End Sub

Private Sub txt3_AfterUpdate()
    If Len(txt3) > 3 Then cmdbUpdate.Enabled = True
End Sub

Private Sub txt4_AfterUpdate()
    If Len(txt4) > 3 Then cmdbUpdate.Enabled = True
End Sub

Private Sub txt5_AfterUpdate()
    If Len(txt5) > 3 Then cmdbUpdate.Enabled = True
End Sub

Private Sub txt6_AfterUpdate()
    If Len(txt6) > 3 Then cmdbUpdate.Enabled = True
End Sub

Private Sub cmdbUpdate_Click()
    
    If txt1.Value = "" And txt2.Value = "" And txt3.Value = "" _
        And txt4.Value = "" And txt5.Value = "" And txt6.Value = "" Then
        MsgBox "Please update data in at least one text box.", 48, "Error"
        Exit Sub
    End If
    
    With Application
        .Calculation = xlCalculationManual
        .ScreenUpdating = False
        .DisplayStatusBar = False
        .EnableEvents = False
    End With
    
    If txt7.Visible = True Then
        cNum = 7
    Else
        cNum = 6
    End If
        
    For x = 1 To cNum
        'AlignLeft = CBool(x = 1 Or x = 7)
        With WS.Cells(CurrentRow, x + 1)
            .Value = Me.Controls("txt" & x).Value
        End With
    Next
    With Application
        .Calculation = xlCalculationAutomatic
        .ScreenUpdating = True
        .DisplayStatusBar = True
        .EnableEvents = True
    End With
    
    MsgBox "Contact modified in " & WS.Name, 64, "Success"
End Sub

Private Sub cmdbNew_Click()
    If txt1.Value = "" And txt2.Value = "" And txt3.Value = "" _
        And txt4.Value = "" And txt5.Value = "" And txt6.Value = "" Then
        MsgBox "Please enter data into at least one field.", 48, "Error"
        Exit Sub
    End If
    NextRow = WS.Cells(WS.Rows.Count, "B").End(xlUp).Row
    If Len(WS.Cells(1, 2).Value) > 0 Then NextRow = NextRow + 1
        If txt7.Visible = True Then
            cNum = 7
        Else
            cNum = 6
        End If
    For x = 1 To cNum
        AlignLeft = CBool(x = 1 Or x = 7)
        With WS.Cells(NextRow, x + 1)
            .Value = Me.Controls("txt" & x).Value
            .EntireColumn.AutoFit
            .HorizontalAlignment = IIf(x = 1 Or x = 7, xlLeft, xlCenter)
            .VerticalAlignment = xlCenter
                With .Font
                     .Name = "Arial"
                     .FontStyle = "Regular"
                     .Size = 10
                End With
        End With
        Controls("txt" & x).Text = ""
    Next
    MsgBox "Contact added to " & WS.Name, 64, "Success"
    Application.ScreenUpdating = False
    Unload Me
    Contacts.Show
    Application.ScreenUpdating = True
End Sub

Private Sub cmdbDelete_Click()
Dim smessage As String
    smessage = "Are you sure you want to delete this contact?" & vbCrLf & vbCrLf & "Name: " & txt2.Text & vbCrLf & "From: " & txt1.Text
    
    If MsgBox(smessage, vbQuestion & vbYesNo, _
              "Delete") = vbYes Then
    WS.Rows(CurrentRow).Delete
    End If
    lastRow = lastRow - 1
    lb.RowSource = "B2:H" & lastRow
End Sub

Private Sub cmdbClose_Click()
Unload Me
End Sub

Private Sub mstrYes_Click()
    txt7.Visible = True
End Sub

Private Sub mstrNo_Click()
    txt7.Visible = False
End Sub

Private Sub lb_Click()
    CurrentRow = lb.ListIndex + 2
    UpdatecmdbChange
End Sub
 
Upvote 0
Hello Alan, thank you for your reply. How about showing the data from B-H without headings to fill in the seven columns and without a spreadsheet to store the results in?
 
Upvote 0
Hello Alan, thank you for your reply. How about showing the data from B-H without headings to fill in the seven columns and without a spreadsheet to store the results in?

Code:
Option Explicit
Dim AlignLeft As Boolean

Dim objCtrl As Control

Dim iPtr As Integer
Dim cNum As Integer
Dim x As Integer
Dim i As Integer

Dim mrCurrentCell As Range

Dim msaWorksheets() As String
Dim msFirstAddress As String

Dim NextRow As Long

Dim mvaSearchResults() As Variant
Dim mvaSearchHeadings() As Variant

Dim mwsSearchResults As Worksheet

Private Sub UserForm_Initialize()
Dim lWSPtr As Long
Dim lWSCount As Long
Dim sCurWS As String

CheckSize

lWSCount = 0
ReDim msaWorksheets(1 To 1)
For lWSPtr = 1 To ThisWorkbook.Sheets.Count
    sCurWS = ThisWorkbook.Sheets(lWSPtr).Name
    If sCurWS <> "Search" And sCurWS <> "SearchResults" Then
        lWSCount = lWSCount + 1
        ReDim Preserve msaWorksheets(1 To lWSCount)
        msaWorksheets(lWSCount) = sCurWS
    End If
Next lWSPtr

Set mrCurrentCell = Nothing
btnSearch.Enabled = False
lblresults.Caption = ""

cbContactType.List = Array("Council Contacts", "Local Contacts", "Housing Associations", "Landlords", "Letting and Selling Agents", "Developers", "Employers")
lblOrganisationName.Visible = False
    txt1.Visible = False
lblContactName.Visible = False
    txt2.Visible = False
lblTelephoneNumber.Visible = False
    txt3.Visible = False
lblEmailAddress.Visible = False
   txt4.Visible = False
lblPostalAddress.Visible = False
  txt5.Visible = False
lblPassword.Visible = False
    txt6.Visible = False
cmdbReset.Enabled = False
cmdbUpdate.Enabled = False
cmdbNew.Enabled = False
cmdbChange.Enabled = False
cmdbDelete.Enabled = False
MLA.Visible = False
mstrAccounts.Visible = False
mstrNo.Value = True
    txt7.Visible = False
With lbs
    .Visible = False
    .ColumnCount = 7
    .ColumnHeads = False
    '    .ColumnWidths = "135 pt;142 pt;135 pt;135 pt;135 pt;135 pt;135 pt;135 pt"
End With
lb.Visible = False
lb.ColumnCount = 7
lb.ColumnHeads = True
lb.ColumnWidths = "135 pt;142 pt;135 pt;135 pt;135 pt;135 pt;135 pt;135 pt"
    For Each objCtrl In Me.Controls
        If Left(objCtrl.Name, 4) = "Text" Then txt7.Visible = False
    Next
    If txt7.Value = "" Then
        txt7.Value = "Example1: " & vbCrLf & "Example2: " & vbCrLf & "Example3: "
    End If

'    'Create Headers
'        .Range("A1").Value = "#"
'        .Range("B1").Value = "Company Name"
'        .Range("C1").Value = "Contact Name"
'        .Range("D1").Value = "Telephone Number"
'        .Range("E1").Value = "Password"
'        .Range("F1").Value = "E-mail Address"
'        .Range("G1").Value = "Postal Address"
'        .Range("H1").Value = "Worksheet"
''ReDim mvaSearchHeadings(1 To 8, 1 To 1)
''mvaSearchHeadings(1, 1) = "#"
''mvaSearchHeadings(2, 1) = "Company Name"
''mvaSearchHeadings(3, 1) = "Contact Name"
''mvaSearchHeadings(4, 1) = "Telephone Number"
''mvaSearchHeadings(5, 1) = "Password"
''mvaSearchHeadings(6, 1) = "E-mail Address"
''mvaSearchHeadings(7, 1) = "Postal Address"
''mvaSearchHeadings(8, 1) = "Worksheet"
''
''On Error Resume Next
''Set mwsSearchResults = Nothing
''Set mwsSearchResults = Sheets("SearchResults")
''If mwsSearchResults Is Nothing Then
''    Set mwsSearchResults = Worksheets.Add(after:=ActiveSheet)
''    With mwsSearchResults
''        .Name = "SearchResults"
''        .Visible = xlSheetHidden
''    End With
''End If
''On Error GoTo 0
''With mwsSearchResults
''    .Cells.Clear
''    .Range("A1").Resize(, UBound(mvaSearchHeadings, 1)).Value = WorksheetFunction.Transpose(mvaSearchHeadings)
''End With
End Sub

Private Sub iptSearch_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
    If KeyCode = 13 Then
        btnSearch_Click
        End If
End Sub

Private Sub CheckSize()
Dim h, w
Dim c As Control
    h = 0: w = 0
    For Each c In Me.Controls
        If c.Visible Then
            If c.Top + c.Height > h Then h = c.Top + c.Height
            If c.Left + c.Width > w Then w = c.Left + c.Width
        End If
    Next c

    If h > 0 And w > 0 Then
        With Me
            .Width = w + 10
            .Height = h + 10
        End With
    End If
End Sub

Private Sub btnSearch_Click()
Dim ip As Integer, r As Integer
Dim sCurName As String
Dim WS As Worksheet, WSnew As Worksheet
Dim lrow As Long
    With Application
        .Calculation = xlCalculationManual
        .ScreenUpdating = False
        .DisplayStatusBar = False
        .EnableEvents = False
    End With
Worksheets.Add
Set WSnew = ActiveSheet
r = 1
For ip = 1 To UBound(msaWorksheets)
    Set WS = Sheets(msaWorksheets(ip))
    Set mrCurrentCell = WS.Cells.Find(what:=iptSearch.Value, LookIn:=xlValues, lookat:=xlPart)
    
    If Not (mrCurrentCell Is Nothing) Then
        msFirstAddress = mrCurrentCell.Address
        Do
            r = r + 1
            Set mrCurrentCell = WS.Cells.FindNext(mrCurrentCell)
            mrCurrentCell.EntireRow.Copy
            WSnew.Paste Destination:=Cells(r, 1)
            WSnew.Cells(r, 8).Value = mrCurrentCell.Worksheet.Name
        Loop While Not mrCurrentCell Is Nothing And mrCurrentCell.Address <> msFirstAddress
    End If
Next ip
With WSnew
    If r < 2 Then
        MsgBox prompt:="Cannot find '" & iptSearch.Value & "'", _
                                        Buttons:=vbOKOnly + vbInformation, _
                                        Title:="Text not found"
    Else
    'Create Headers
        .Range("A1").Value = "#"
        .Range("B1").Value = "Company Name"
        .Range("C1").Value = "Contact Name"
        .Range("D1").Value = "Telephone Number"
        .Range("E1").Value = "Password"
        .Range("F1").Value = "E-mail Address"
        .Range("G1").Value = "Postal Address"
        .Range("H1").Value = "Worksheet"
        .Range("A2").Value = 1
            If r > 2 Then .Range("A2").AutoFill Destination:=.Range("A2:A" & r), Type:=xlLinearTrend
    'populate listbox
        With Me.lbs
            .Visible = True
            .ColumnCount = 8
            .ColumnWidths = "15 pt;142 pt;135 pt;135 pt;135 pt;135 pt;135 pt;85 pt"
            .ColumnHeads = False
            .List = WSnew.Range("A1:H" & r).Value

        End With
        
        With Application
            .Calculation = xlCalculationAutomatic
            .ScreenUpdating = True
            .DisplayStatusBar = True
            .EnableEvents = True
        End With
    End If
    Application.DisplayAlerts = False
        .Delete
    Application.DisplayAlerts = True
End With
    
End Sub

Private Sub iptSearch_Change()
Dim lPointer As Long
Dim lStartPointer As Long
Dim lPtr As Long
Dim lFoundCount As Long
Dim lColumnPointer As Long
Dim lResultsColPtr As Long

Dim rResultsRange As Range

Dim sCurName As String
Dim sCurHeading As String
Dim sCurrentFoundAddress As String

Dim vaResults As Variant
Dim vaDataLine As Variant
Dim vaHeadingLine As Variant

Dim WS As Worksheet

Set mrCurrentCell = Nothing
lStartPointer = 1

lbs.Clear
lblresults.Caption = ""
lFoundCount = -1

If iptSearch.Text <> "" Then
    
    ReDim mvaSearchResults(1 To 7, 1 To 1)
    
    For lPointer = lStartPointer To UBound(msaWorksheets)
        msFirstAddress = ""
        Set WS = Sheets(msaWorksheets(lPointer))
        vaHeadingLine = Intersect(WS.Rows(1), WS.UsedRange)
        For lPtr = 1 To UBound(vaHeadingLine, 2)
            vaHeadingLine(1, lPtr) = LCase$(Replace$(vaHeadingLine(1, lPtr), " ", ""))
        Next lPtr
        
        Set mrCurrentCell = WS.Cells.Find(what:=iptSearch.Value, LookIn:=xlValues, lookat:=xlPart)
        Do While Not (mrCurrentCell Is Nothing)
            sCurrentFoundAddress = WS.Name & "!" & mrCurrentCell.Address(False, False)
            If sCurrentFoundAddress = msFirstAddress Then Exit Do
            If msFirstAddress = "" Then msFirstAddress = sCurrentFoundAddress
            If mrCurrentCell.Row > 1 And mrCurrentCell.Column > 1 And mrCurrentCell.Column < 9 Then
                lFoundCount = lFoundCount + 1
                ReDim Preserve mvaSearchResults(1 To 7, 1 To lFoundCount + 1)
                vaDataLine = WS.Range(WS.Cells(mrCurrentCell.Row, 2).Address).Resize(, 7).Value
                
                For lResultsColPtr = 1 To 7
                    mvaSearchResults(lResultsColPtr, lFoundCount + 1) = vaDataLine(1, lResultsColPtr)
                Next lResultsColPtr
            End If
            Set mrCurrentCell = WS.Cells.FindNext(mrCurrentCell)
        Loop
    Next lPointer
    If lFoundCount < 0 Then
        lblresults.Caption = "No entries found"
    Else
'        Set rResultsRange = mwsSearchResults.Range("A2").Resize(UBound(mvaSearchResults, 2), _
'                                                                UBound(mvaSearchResults, 1))
'        rResultsRange.Value = WorksheetFunction.Transpose(mvaSearchResults)
'        lbs.RowSource = mwsSearchResults.Name & "!" & rResultsRange.Address
        If lFoundCount = 0 Then
            With lbs
                .AddItem
                For lPtr = 1 To 7
                    .List(0, lPtr - 1) = mvaSearchResults(lPtr, 1)
                Next lPtr
            End With
        Else
            lbs.List = WorksheetFunction.Transpose(mvaSearchResults)
        End If
        lblresults.Caption = lFoundCount + 1 & " entries found"
            
    End If
End If

lbs.Visible = lFoundCount > -1
End Sub

Private Function GetHeadingColumn(ByVal Heading As String, ByVal HeadingArray As Variant) As Long
Dim lPtr As Long

Heading = LCase$(Replace(Heading, " ", ""))
GetHeadingColumn = 0
For lPtr = 1 To UBound(HeadingArray, 2)
    If Heading = LCase$(HeadingArray(1, lPtr)) Then
        GetHeadingColumn = lPtr
        Exit For
    End If
Next lPtr
End Function
Private Sub cbContactType_Change()
    cmdbNew.Enabled = CBool(cbContactType.ListIndex <> -1)
    mstrNo.Value = True
    If cbContactType.Enabled Then Set WS = Worksheets(cbContactType.Text)
    
    If cbContactType.Value = "Housing Associations" Or _
       cbContactType.Value = "Landlords" Then
       mstrAccounts.Visible = True
       MLA.Visible = True
    Else
        mstrAccounts.Visible = False
        MLA.Visible = False
    End If
    
    lastRow = WS.Range("B" & Rows.Count).End(xlUp).Row
    CurrentRow = lastRow + 1
    
    'loop thru and clear textboxes
    For i = 1 To 6
        Contacts.Controls("txt" & i).Value = ""
        Contacts.Controls("txt" & i).BackColor = vbWhite
        Contacts.Controls("txt" & i).ForeColor = vbBlack
        Contacts.Controls("txt" & i).Visible = True
    Next i
    
    Contacts.dtaRow.Caption = lastRow - 1 & " Record"
    
    lblOrganisationName.Visible = True
    lblContactName.Visible = True
    lblTelephoneNumber.Visible = True
    lblEmailAddress.Visible = True
    lblPostalAddress.Visible = True
    lblPassword.Visible = True
    cmdbReset.Enabled = True
    cmdbChange.Enabled = True
    cmdbDelete.Enabled = True
    lb.Visible = True
    WS.Activate
    lb.RowSource = "B2:H" & lastRow
End Sub

Private Sub cmdbChange_SpinUp()
    If CurrentRow < lastRow Then
        CurrentRow = CurrentRow + 1
        UpdatecmdbChange
    Else
        CurrentRow = 2
        UpdatecmdbChange
    End If
    lb.ListIndex = CurrentRow - 2
End Sub

Private Sub cmdbChange_SpinDown()
    If CurrentRow > 2 Then
        CurrentRow = CurrentRow - 1
        UpdatecmdbChange
    Else
        CurrentRow = lastRow
        UpdatecmdbChange
    End If
    lb.ListIndex = CurrentRow - 2
End Sub

Private Sub cmdbReset_Click()
    Application.ScreenUpdating = False
    Unload Me
    Contacts.Show
    Application.ScreenUpdating = True
End Sub

Private Sub txt1_AfterUpdate()
    If Len(txt1) > 3 Then cmdbUpdate.Enabled = True
End Sub

Private Sub txt2_AfterUpdate()
    If Len(txt2) > 3 Then cmdbUpdate.Enabled = True
End Sub

Private Sub txt3_AfterUpdate()
    If Len(txt3) > 3 Then cmdbUpdate.Enabled = True
End Sub

Private Sub txt4_AfterUpdate()
    If Len(txt4) > 3 Then cmdbUpdate.Enabled = True
End Sub

Private Sub txt5_AfterUpdate()
    If Len(txt5) > 3 Then cmdbUpdate.Enabled = True
End Sub

Private Sub txt6_AfterUpdate()
    If Len(txt6) > 3 Then cmdbUpdate.Enabled = True
End Sub

Private Sub cmdbUpdate_Click()
    
    If txt1.Value = "" And txt2.Value = "" And txt3.Value = "" _
        And txt4.Value = "" And txt5.Value = "" And txt6.Value = "" Then
        MsgBox "Please update data in at least one text box.", 48, "Error"
        Exit Sub
    End If
    
    With Application
        .Calculation = xlCalculationManual
        .ScreenUpdating = False
        .DisplayStatusBar = False
        .EnableEvents = False
    End With
    
    If txt7.Visible = True Then
        cNum = 7
    Else
        cNum = 6
    End If
        
    For x = 1 To cNum
        'AlignLeft = CBool(x = 1 Or x = 7)
        With WS.Cells(CurrentRow, x + 1)
            .Value = Me.Controls("txt" & x).Value
        End With
    Next
    With Application
        .Calculation = xlCalculationAutomatic
        .ScreenUpdating = True
        .DisplayStatusBar = True
        .EnableEvents = True
    End With
    
    MsgBox "Contact modified in " & WS.Name, 64, "Success"
End Sub

Private Sub cmdbNew_Click()
    If txt1.Value = "" And txt2.Value = "" And txt3.Value = "" _
        And txt4.Value = "" And txt5.Value = "" And txt6.Value = "" Then
        MsgBox "Please enter data into at least one field.", 48, "Error"
        Exit Sub
    End If
    NextRow = WS.Cells(WS.Rows.Count, "B").End(xlUp).Row
    If Len(WS.Cells(1, 2).Value) > 0 Then NextRow = NextRow + 1
        If txt7.Visible = True Then
            cNum = 7
        Else
            cNum = 6
        End If
    For x = 1 To cNum
        AlignLeft = CBool(x = 1 Or x = 7)
        With WS.Cells(NextRow, x + 1)
            .Value = Me.Controls("txt" & x).Value
            .EntireColumn.AutoFit
            .HorizontalAlignment = IIf(x = 1 Or x = 7, xlLeft, xlCenter)
            .VerticalAlignment = xlCenter
                With .Font
                     .Name = "Arial"
                     .FontStyle = "Regular"
                     .Size = 10
                End With
        End With
        Controls("txt" & x).Text = ""
    Next
    MsgBox "Contact added to " & WS.Name, 64, "Success"
    Application.ScreenUpdating = False
    Unload Me
    Contacts.Show
    Application.ScreenUpdating = True
End Sub

Private Sub cmdbDelete_Click()
Dim smessage As String
    smessage = "Are you sure you want to delete this contact?" & vbCrLf & vbCrLf & "Name: " & txt2.Text & vbCrLf & "From: " & txt1.Text
    
    If MsgBox(smessage, vbQuestion & vbYesNo, _
              "Delete") = vbYes Then
    WS.Rows(CurrentRow).Delete
    End If
    lastRow = lastRow - 1
    lb.RowSource = "B2:H" & lastRow
End Sub

Private Sub cmdbClose_Click()
Unload Me
End Sub

Private Sub mstrYes_Click()
    txt7.Visible = True
End Sub

Private Sub mstrNo_Click()
    txt7.Visible = False
End Sub

Private Sub lb_Click()
    CurrentRow = lb.ListIndex + 2
    UpdatecmdbChange
End Sub
 
Upvote 0
That's great, thanks so much. The functionality that you introduced for the listbox on the search tab, can this be introduced for the buttons on the add/update tab s that the form behaviour is consistent? The buttons should not be visible until a selection is made from the combobox.

If so, it would be a good idea to have a 'close' button that only shows when all the other buttons are not visible prior to a selection being made in the combobox. It should appear to the right hand side of the combobox.

Also, is there a way to filter which columns show on the search results page using checkboxes? I'd like a checkbox for each column to make it easy to only see exactly what the user wants to see. It could be that they only want to view the contact name and telephone number or they only want the organisation name and email address.

I have updated the file on dropbox: https://www.dropbox.com/s/k4uvgpbd6wbxooe/AltBKContacts.xlsm?dl=0

Code:
Option ExplicitDim AlignLeft As Boolean


Dim objCtrl As Control


Dim iPtr As Integer
Dim cNum As Integer
Dim x As Integer
Dim i As Integer


Dim mrCurrentCell As Range


Dim msaWorksheets() As String
Dim msFirstAddress As String


Dim NextRow As Long


Dim mvaSearchResults() As Variant
Dim mvaSearchHeadings() As Variant


Dim mwsSearchResults As Worksheet


Private Sub UserForm_Initialize()
Dim lWSPtr As Long
Dim lWSCount As Long
Dim sCurWS As String


CheckSize


lWSCount = 0
ReDim msaWorksheets(1 To 1)
For lWSPtr = 1 To ThisWorkbook.Sheets.Count
    sCurWS = ThisWorkbook.Sheets(lWSPtr).Name
    If sCurWS <> "Search" And sCurWS <> "SearchResults" Then
        lWSCount = lWSCount + 1
        ReDim Preserve msaWorksheets(1 To lWSCount)
        msaWorksheets(lWSCount) = sCurWS
    End If
Next lWSPtr


Set mrCurrentCell = Nothing
lblresults.Caption = ""


cbContactType.List = Array("Council Contacts", "Local Contacts", "Housing Associations", "Landlords", "Letting and Selling Agents", "Developers", "Employers")
lblOrganisationName.Visible = False
    txt1.Visible = False
lblContactName.Visible = False
    txt2.Visible = False
lblTelephoneNumber.Visible = False
    txt3.Visible = False
lblEmailAddress.Visible = False
   txt4.Visible = False
lblPostalAddress.Visible = False
  txt5.Visible = False
lblPassword.Visible = False
    txt6.Visible = False
cmdbReset.Enabled = False
cmdbUpdate.Enabled = False
cmdbNew.Enabled = False
cmdbChange.Enabled = False
cmdbDelete.Enabled = False
MLA.Visible = False
mstrAccounts.Visible = False
mstrNo.Value = True
    txt7.Visible = False
With lbs
    .Visible = False
    .ColumnCount = 7
    .ColumnHeads = False
    '    .ColumnWidths = "135 pt;142 pt;135 pt;135 pt;135 pt;135 pt;135 pt;135 pt"
End With
lb.Visible = False
lb.ColumnCount = 7
lb.ColumnHeads = True
lb.ColumnWidths = "135 pt;142 pt;135 pt;135 pt;135 pt;135 pt;135 pt;135 pt"
    For Each objCtrl In Me.Controls
        If Left(objCtrl.Name, 4) = "Text" Then txt7.Visible = False
    Next
    If txt7.Value = "" Then
        txt7.Value = "Example1: " & vbCrLf & "Example2: " & vbCrLf & "Example3: "
    End If


'    'Create Headers
'        .Range("A1").Value = "#"
'        .Range("B1").Value = "Company Name"
'        .Range("C1").Value = "Contact Name"
'        .Range("D1").Value = "Telephone Number"
'        .Range("E1").Value = "Password"
'        .Range("F1").Value = "E-mail Address"
'        .Range("G1").Value = "Postal Address"
'        .Range("H1").Value = "Worksheet"
'ReDim mvaSearchHeadings(1 To 8, 1 To 1)
'mvaSearchHeadings(1, 1) = "#"
'mvaSearchHeadings(2, 1) = "Company Name"
'mvaSearchHeadings(3, 1) = "Contact Name"
'mvaSearchHeadings(4, 1) = "Telephone Number"
'mvaSearchHeadings(5, 1) = "Password"
'mvaSearchHeadings(6, 1) = "E-mail Address"
'mvaSearchHeadings(7, 1) = "Postal Address"
'mvaSearchHeadings(8, 1) = "Worksheet"
'
'On Error Resume Next
'Set mwsSearchResults = Nothing
'Set mwsSearchResults = Sheets("SearchResults")
'If mwsSearchResults Is Nothing Then
'    Set mwsSearchResults = Worksheets.Add(after:=ActiveSheet)
'    With mwsSearchResults
'        .Name = "SearchResults"
'        .Visible = xlSheetHidden
'    End With
'End If
'On Error GoTo 0
'With mwsSearchResults
'    .Cells.Clear
'    .Range("A1").Resize(, UBound(mvaSearchHeadings, 1)).Value = WorksheetFunction.Transpose(mvaSearchHeadings)
'End With
End Sub


Private Sub CheckSize()
Dim h, w
Dim c As Control
    h = 0: w = 0
    For Each c In Me.Controls
        If c.Visible Then
            If c.Top + c.Height > h Then h = c.Top + c.Height
            If c.Left + c.Width > w Then w = c.Left + c.Width
        End If
    Next c


    If h > 0 And w > 0 Then
        With Me
            .Width = w + 10
            .Height = h + 10
        End With
    End If
End Sub


Private Sub iptSearch_Change()
Dim lPointer As Long
Dim lStartPointer As Long
Dim lPtr As Long
Dim lFoundCount As Long
Dim lColumnPointer As Long
Dim lResultsColPtr As Long


Dim rResultsRange As Range


Dim sCurName As String
Dim sCurHeading As String
Dim sCurrentFoundAddress As String


Dim vaResults As Variant
Dim vaDataLine As Variant
Dim vaHeadingLine As Variant


Dim WS As Worksheet


Set mrCurrentCell = Nothing
lStartPointer = 1


lbs.Clear
lblresults.Caption = ""
lFoundCount = -1


If iptSearch.Text <> "" Then
    
    ReDim mvaSearchResults(1 To 7, 1 To 1)
    
    For lPointer = lStartPointer To UBound(msaWorksheets)
        msFirstAddress = ""
        Set WS = Sheets(msaWorksheets(lPointer))
        vaHeadingLine = Intersect(WS.Rows(1), WS.UsedRange)
        For lPtr = 1 To UBound(vaHeadingLine, 2)
            vaHeadingLine(1, lPtr) = LCase$(Replace$(vaHeadingLine(1, lPtr), " ", ""))
        Next lPtr
        
        Set mrCurrentCell = WS.Cells.Find(what:=iptSearch.Value, LookIn:=xlValues, lookat:=xlPart)
        Do While Not (mrCurrentCell Is Nothing)
            sCurrentFoundAddress = WS.Name & "!" & mrCurrentCell.Address(False, False)
            If sCurrentFoundAddress = msFirstAddress Then Exit Do
            If msFirstAddress = "" Then msFirstAddress = sCurrentFoundAddress
            If mrCurrentCell.Row > 1 And mrCurrentCell.Column > 1 And mrCurrentCell.Column < 9 Then
                lFoundCount = lFoundCount + 1
                ReDim Preserve mvaSearchResults(1 To 7, 1 To lFoundCount + 1)
                vaDataLine = WS.Range(WS.Cells(mrCurrentCell.Row, 2).Address).Resize(, 7).Value
                
                For lResultsColPtr = 1 To 7
                    mvaSearchResults(lResultsColPtr, lFoundCount + 1) = vaDataLine(1, lResultsColPtr)
                Next lResultsColPtr
            End If
            Set mrCurrentCell = WS.Cells.FindNext(mrCurrentCell)
        Loop
    Next lPointer
    If lFoundCount < 0 Then
        lblresults.Caption = "No results found"
    Else
'        Set rResultsRange = mwsSearchResults.Range("A2").Resize(UBound(mvaSearchResults, 2), _
'                                                                UBound(mvaSearchResults, 1))
'        rResultsRange.Value = WorksheetFunction.Transpose(mvaSearchResults)
'        lbs.RowSource = mwsSearchResults.Name & "!" & rResultsRange.Address
        If lFoundCount = 0 Then
            With lbs
                .AddItem
                For lPtr = 1 To 7
                    .List(0, lPtr - 1) = mvaSearchResults(lPtr, 1)
                Next lPtr
            End With
        Else
            lbs.List = WorksheetFunction.Transpose(mvaSearchResults)
        End If
        lblresults.Caption = lFoundCount + 1 & " results found"
            
    End If
End If


lbs.Visible = lFoundCount > -1
End Sub


Private Function GetHeadingColumn(ByVal Heading As String, ByVal HeadingArray As Variant) As Long
Dim lPtr As Long


Heading = LCase$(Replace(Heading, " ", ""))
GetHeadingColumn = 0
For lPtr = 1 To UBound(HeadingArray, 2)
    If Heading = LCase$(HeadingArray(1, lPtr)) Then
        GetHeadingColumn = lPtr
        Exit For
    End If
Next lPtr
End Function
Private Sub cbContactType_Change()
    cmdbNew.Enabled = CBool(cbContactType.ListIndex <> -1)
    mstrNo.Value = True
    If cbContactType.Enabled Then Set WS = Worksheets(cbContactType.Text)
    
    If cbContactType.Value = "Housing Associations" Or _
       cbContactType.Value = "Landlords" Then
       mstrAccounts.Visible = True
       MLA.Visible = True
    Else
        mstrAccounts.Visible = False
        MLA.Visible = False
    End If
    
    lastRow = WS.Range("B" & Rows.Count).End(xlUp).Row
    CurrentRow = lastRow + 1
    
    'loop thru and clear textboxes
    For i = 1 To 6
        Contacts.Controls("txt" & i).Value = ""
        Contacts.Controls("txt" & i).BackColor = vbWhite
        Contacts.Controls("txt" & i).ForeColor = vbBlack
        Contacts.Controls("txt" & i).Visible = True
    Next i
    
    Contacts.dtaRow.Caption = lastRow - 1 & " Record"
    
    lblOrganisationName.Visible = True
    lblContactName.Visible = True
    lblTelephoneNumber.Visible = True
    lblEmailAddress.Visible = True
    lblPostalAddress.Visible = True
    lblPassword.Visible = True
    cmdbReset.Enabled = True
    cmdbChange.Enabled = True
    cmdbDelete.Enabled = True
    lb.Visible = True
    WS.Activate
    lb.RowSource = "B2:H" & lastRow
End Sub


Private Sub cmdbChange_SpinUp()
    If CurrentRow < lastRow Then
        CurrentRow = CurrentRow + 1
        UpdatecmdbChange
    Else
        CurrentRow = 2
        UpdatecmdbChange
    End If
    lb.ListIndex = CurrentRow - 2
End Sub


Private Sub cmdbChange_SpinDown()
    If CurrentRow > 2 Then
        CurrentRow = CurrentRow - 1
        UpdatecmdbChange
    Else
        CurrentRow = lastRow
        UpdatecmdbChange
    End If
    lb.ListIndex = CurrentRow - 2
End Sub


Private Sub cmdbReset_Click()
    Application.ScreenUpdating = False
    Unload Me
    Contacts.Show
    Application.ScreenUpdating = True
End Sub


Private Sub txt1_AfterUpdate()
    If Len(txt1) > 3 Then cmdbUpdate.Enabled = True
End Sub


Private Sub txt2_AfterUpdate()
    If Len(txt2) > 3 Then cmdbUpdate.Enabled = True
End Sub


Private Sub txt3_AfterUpdate()
    If Len(txt3) > 3 Then cmdbUpdate.Enabled = True
End Sub


Private Sub txt4_AfterUpdate()
    If Len(txt4) > 3 Then cmdbUpdate.Enabled = True
End Sub


Private Sub txt5_AfterUpdate()
    If Len(txt5) > 3 Then cmdbUpdate.Enabled = True
End Sub


Private Sub txt6_AfterUpdate()
    If Len(txt6) > 3 Then cmdbUpdate.Enabled = True
End Sub


Private Sub cmdbUpdate_Click()
    
    If txt1.Value = "" And txt2.Value = "" And txt3.Value = "" _
        And txt4.Value = "" And txt5.Value = "" And txt6.Value = "" Then
        MsgBox "Please update data in at least one text box.", 48, "Error"
        Exit Sub
    End If
    
    With Application
        .Calculation = xlCalculationManual
        .ScreenUpdating = False
        .DisplayStatusBar = False
        .EnableEvents = False
    End With
    
    If txt7.Visible = True Then
        cNum = 7
    Else
        cNum = 6
    End If
        
    For x = 1 To cNum
        'AlignLeft = CBool(x = 1 Or x = 7)
        With WS.Cells(CurrentRow, x + 1)
            .Value = Me.Controls("txt" & x).Value
        End With
    Next
    With Application
        .Calculation = xlCalculationAutomatic
        .ScreenUpdating = True
        .DisplayStatusBar = True
        .EnableEvents = True
    End With
    
    MsgBox "Contact modified in " & WS.Name, 64, "Success"
End Sub


Private Sub cmdbNew_Click()
    If txt1.Value = "" And txt2.Value = "" And txt3.Value = "" _
        And txt4.Value = "" And txt5.Value = "" And txt6.Value = "" Then
        MsgBox "Please enter data into at least one field.", 48, "Error"
        Exit Sub
    End If
    NextRow = WS.Cells(WS.Rows.Count, "B").End(xlUp).Row
    If Len(WS.Cells(1, 2).Value) > 0 Then NextRow = NextRow + 1
        If txt7.Visible = True Then
            cNum = 7
        Else
            cNum = 6
        End If
    For x = 1 To cNum
        AlignLeft = CBool(x = 1 Or x = 7)
        With WS.Cells(NextRow, x + 1)
            .Value = Me.Controls("txt" & x).Value
            .EntireColumn.AutoFit
            .HorizontalAlignment = IIf(x = 1 Or x = 7, xlLeft, xlCenter)
            .VerticalAlignment = xlCenter
                With .Font
                     .Name = "Arial"
                     .FontStyle = "Regular"
                     .Size = 10
                End With
        End With
        Controls("txt" & x).Text = ""
    Next
    MsgBox "Contact added to " & WS.Name, 64, "Success"
    Application.ScreenUpdating = False
    Unload Me
    Contacts.Show
    Application.ScreenUpdating = True
End Sub


Private Sub cmdbDelete_Click()
Dim smessage As String
    smessage = "Are you sure you want to delete this contact?" & vbCrLf & vbCrLf & "Name: " & txt2.Text & vbCrLf & "From: " & txt1.Text
    
    If MsgBox(smessage, vbQuestion & vbYesNo, _
              "Delete") = vbYes Then
    WS.Rows(CurrentRow).Delete
    End If
    lastRow = lastRow - 1
    lb.RowSource = "B2:H" & lastRow
End Sub


Private Sub cmdbClose_Click()
Unload Me
End Sub


Private Sub mstrYes_Click()
    txt7.Visible = True
End Sub


Private Sub mstrNo_Click()
    txt7.Visible = False
End Sub


Private Sub lb_Click()
    CurrentRow = lb.ListIndex + 2
    UpdatecmdbChange
End Sub
 
Upvote 0
Hi,
Addressing the requirement for the user to specify what columns to see, give the following a test drive.
You first need to add a Listbox named "LstDisplayHeadings":
Code:
Option Explicit
Dim AlignLeft As Boolean

Dim objCtrl As Control

Dim iPtr As Integer
Dim cNum As Integer
Dim x As Integer
Dim i As Integer

Dim mlHeadingsCount As Long
Dim mrCurrentCell As Range

Dim msaWorksheets() As String
Dim msFirstAddress As String

Dim NextRow As Long

Dim mvaSearchResults() As Variant
Dim mvaSearchHeadings As Variant

Dim mwsSearchResults As Worksheet

Private Sub lstDisplayHeadings_Change()
Dim bEnable As Boolean
Dim lPtr As Long
Dim lHeadingsPtr As Long

ReDim mvaSearchHeadings(1 To 1, 1 To 1)
mlHeadingsCount = 0
bEnable = False
With lstDisplayHeadings
    For lPtr = 0 To .ListCount - 1
        If .Selected(lPtr) = True Then
            bEnable = True
            mlHeadingsCount = mlHeadingsCount + 1
            ReDim Preserve mvaSearchHeadings(1 To 1, 1 To mlHeadingsCount)
            mvaSearchHeadings(1, mlHeadingsCount) = .List(lPtr)
        End If
    Next lPtr
End With
With iptSearch
    .Visible = bEnable
End With

Call iptSearch_Change
End Sub

Private Sub MultiPage1_Change()

End Sub

Private Sub UserForm_Initialize()
Dim bHeadingFound As Boolean

Dim lColumnPtr1 As Long
Dim lColumnPtr2 As Long
Dim lWSPtr As Long
Dim lWSCount As Long

Dim sCurWS As String
Dim sCurHeading1 As String
Dim sCurHeading2 As String
Dim vaCurHeadings As Variant

CheckSize

lWSCount = 0
ReDim msaWorksheets(1 To 1)
For lWSPtr = 1 To ThisWorkbook.Sheets.Count
    sCurWS = ThisWorkbook.Sheets(lWSPtr).Name
    If sCurWS <> "Search" And sCurWS <> "SearchResults" Then
        lWSCount = lWSCount + 1
        ReDim Preserve msaWorksheets(1 To lWSCount)
        msaWorksheets(lWSCount) = sCurWS
    End If
Next lWSPtr

Set mrCurrentCell = Nothing
lblresults.Caption = ""

cbContactType.List = Array("Council Contacts", "Local Contacts", "Housing Associations", "Landlords", "Letting and Selling Agents", "Developers", "Employers")
lblOrganisationName.Visible = False
    txt1.Visible = False
lblContactName.Visible = False
    txt2.Visible = False
lblTelephoneNumber.Visible = False
    txt3.Visible = False
lblEmailAddress.Visible = False
   txt4.Visible = False
lblPostalAddress.Visible = False
  txt5.Visible = False
lblPassword.Visible = False
    txt6.Visible = False
cmdbReset.Enabled = False
cmdbUpdate.Enabled = False
cmdbNew.Enabled = False
cmdbChange.Enabled = False
cmdbDelete.Enabled = False
MLA.Visible = False
mstrAccounts.Visible = False
mstrNo.Value = True
    txt7.Visible = False
With lbs
    .Visible = False
'    .ColumnCount = 7
    .ColumnHeads = False
    '    .ColumnWidths = "135 pt;142 pt;135 pt;135 pt;135 pt;135 pt;135 pt;135 pt"
End With
lb.Visible = False
lb.ColumnCount = 7
lb.ColumnHeads = True
lb.ColumnWidths = "135 pt;142 pt;135 pt;135 pt;135 pt;135 pt;135 pt;135 pt"

For Each objCtrl In Me.Controls
    If Left(objCtrl.Name, 4) = "Text" Then txt7.Visible = False
Next
If txt7.Value = "" Then
    txt7.Value = "Example1: " & vbCrLf & "Example2: " & vbCrLf & "Example3: "
End If

'-- Assemble column headings --
mvaSearchHeadings = False
For lWSPtr = 1 To UBound(msaWorksheets)
    vaCurHeadings = Sheets(msaWorksheets(lWSPtr)).Range("B1:H1").Value
    For lColumnPtr1 = 1 To UBound(vaCurHeadings, 2)
        sCurHeading1 = "" & LCase$(Replace(vaCurHeadings(1, lColumnPtr1), " ", ""))
        If sCurHeading1 <> "" Then
            If IsArray(mvaSearchHeadings) Then
                bHeadingFound = False
                For lColumnPtr2 = 1 To UBound(mvaSearchHeadings, 2)
                    If LCase$(Replace(mvaSearchHeadings(1, lColumnPtr2), " ", "")) = sCurHeading1 Then
                        bHeadingFound = True
                        Exit For
                    End If
                Next lColumnPtr2
                If bHeadingFound = False Then
                    lColumnPtr2 = UBound(mvaSearchHeadings, 2) + 1
                    ReDim Preserve mvaSearchHeadings(1 To 1, 1 To lColumnPtr2)
                    mvaSearchHeadings(1, lColumnPtr2) = vaCurHeadings(1, lColumnPtr1)
                End If
            Else
                ReDim mvaSearchHeadings(1 To 1, 1 To 1)
                mvaSearchHeadings(1, 1) = vaCurHeadings(1, lColumnPtr1)
            End If
        End If
    Next lColumnPtr1
Next lWSPtr

'-- Sort column headings --
For lColumnPtr1 = 1 To UBound(mvaSearchHeadings, 2) - 1
    sCurHeading1 = mvaSearchHeadings(1, lColumnPtr1)
    For lColumnPtr2 = lColumnPtr1 + 1 To UBound(mvaSearchHeadings, 2)
        sCurHeading2 = CStr(mvaSearchHeadings(1, lColumnPtr2))
        If sCurHeading1 > sCurHeading2 Then
            mvaSearchHeadings(1, lColumnPtr1) = sCurHeading2
            mvaSearchHeadings(1, lColumnPtr2) = sCurHeading1
            sCurHeading1 = sCurHeading2
        End If
    Next lColumnPtr2
Next lColumnPtr1

With lstDisplayHeadings
    .ColumnCount = 1
    .ListStyle = fmListStyleOption
    .List = WorksheetFunction.Transpose(mvaSearchHeadings)
    .MultiSelect = fmMultiSelectMulti
End With
With iptSearch
    .Visible = False
End With
End Sub

Private Sub CheckSize()
Dim h, w
Dim c As Control
    h = 0: w = 0
    For Each c In Me.Controls
        If c.Visible Then
            If c.Top + c.Height > h Then h = c.Top + c.Height
            If c.Left + c.Width > w Then w = c.Left + c.Width
        End If
    Next c

    If h > 0 And w > 0 Then
        With Me
            .Width = w + 10
            .Height = h + 10
        End With
    End If
End Sub

Private Sub iptSearch_Change()
Dim lPointer As Long
Dim lStartPointer As Long
Dim lPtr As Long
Dim lPtr1 As Long
Dim lFoundCount As Long
Dim lColumnPointer As Long
Dim lResultsColPtr As Long
Dim laHeadingColumns() As Long

Dim rResultsRange As Range

Dim sCurName As String
Dim sCurHeading As String
Dim sCurrentFoundAddress As String

Dim vaResults As Variant
Dim vaDataLine As Variant
Dim vaHeadingLine As Variant

Dim WS As Worksheet

Set mrCurrentCell = Nothing
lStartPointer = 1

With lbs
    .Clear
    .ColumnCount = mlHeadingsCount
End With

lblresults.Caption = ""
lFoundCount = -1

If iptSearch.Text <> "" Then
    
    ReDim mvaSearchResults(1 To mlHeadingsCount, 1 To 1)
    
    For lPointer = lStartPointer To UBound(msaWorksheets)
        msFirstAddress = ""
        Set WS = Sheets(msaWorksheets(lPointer))
        
        '-- Find heading columns and store in array --
        ReDim laHeadingColumns(1 To mlHeadingsCount)
        lPtr1 = 0
        For lPtr = 1 To mlHeadingsCount
            On Error Resume Next
            lColumnPointer = 0
            lColumnPointer = WorksheetFunction.Match(mvaSearchHeadings(1, lPtr), Intersect(WS.Rows("1:1"), WS.UsedRange), 0)
            On Error Resume Next
            laHeadingColumns(lPtr) = lColumnPointer
        Next lPtr
        
        vaHeadingLine = Intersect(WS.Rows(1), WS.UsedRange)
        
        Set mrCurrentCell = WS.Cells.Find(what:=iptSearch.Value, LookIn:=xlValues, lookat:=xlPart)
        Do While Not (mrCurrentCell Is Nothing)
            sCurrentFoundAddress = WS.Name & "!" & mrCurrentCell.Address(False, False)
            If sCurrentFoundAddress = msFirstAddress Then Exit Do
            If msFirstAddress = "" Then msFirstAddress = sCurrentFoundAddress
            If mrCurrentCell.Row > 1 _
            And IsaHeaderColumn(mrCurrentCell.Column, laHeadingColumns) Then
                lFoundCount = lFoundCount + 1
                ReDim Preserve mvaSearchResults(1 To mlHeadingsCount, 1 To lFoundCount + 1)
                
'                vaDataLine = WS.Range(WS.Cells(mrCurrentCell.Row, 2).Address).Resize(, 7).Value
                vaDataLine = Intersect(WS.UsedRange, WS.Rows(mrCurrentCell.Row))
                
                For lResultsColPtr = 1 To mlHeadingsCount
                    lColumnPointer = laHeadingColumns(lResultsColPtr)
                    If lColumnPointer > 0 Then
                        mvaSearchResults(lResultsColPtr, lFoundCount + 1) = vaDataLine(1, lColumnPointer)
                    End If
                Next lResultsColPtr
            End If
            Set mrCurrentCell = WS.Cells.FindNext(mrCurrentCell)
        Loop
    Next lPointer
    If lFoundCount < 0 Then
        lblresults.Caption = "No results found"
    Else
        If lFoundCount = 0 Then
            With lbs
                .AddItem
                For lPtr = 1 To mlHeadingsCount
                    .List(0, lPtr - 1) = mvaSearchResults(lPtr, 1)
                Next lPtr
            End With
        Else
            lbs.List = WorksheetFunction.Transpose(mvaSearchResults)
        End If
        lblresults.Caption = lFoundCount + 1 & " results found"
            
    End If
End If

lbs.Visible = lFoundCount > -1
End Sub

Private Function IsaHeaderColumn(ByVal Columnx As Long, ByRef ColumnArray() As Long) As Boolean
Dim lCol As Long

IsaHeaderColumn = False
For lCol = LBound(ColumnArray) To UBound(ColumnArray)
    If ColumnArray(lCol) = Columnx Then
        IsaHeaderColumn = True
        Exit For
    End If
Next lCol
End Function
Private Function GetHeadingColumn(ByVal Heading As String, ByVal HeadingArray As Variant) As Long
Dim lPtr As Long

Heading = LCase$(Replace(Heading, " ", ""))
GetHeadingColumn = 0
For lPtr = 1 To UBound(HeadingArray, 2)
    If Heading = LCase$(HeadingArray(1, lPtr)) Then
        GetHeadingColumn = lPtr
        Exit For
    End If
Next lPtr
End Function
Private Sub cbContactType_Change()
    cmdbNew.Enabled = CBool(cbContactType.ListIndex <> -1)
    mstrNo.Value = True
    If cbContactType.Enabled Then Set WS = Worksheets(cbContactType.Text)
    
    If cbContactType.Value = "Housing Associations" Or _
       cbContactType.Value = "Landlords" Then
       mstrAccounts.Visible = True
       MLA.Visible = True
    Else
        mstrAccounts.Visible = False
        MLA.Visible = False
    End If
    
    lastRow = WS.Range("B" & Rows.Count).End(xlUp).Row
    CurrentRow = lastRow + 1
    
    'loop thru and clear textboxes
    For i = 1 To 6
        Contacts.Controls("txt" & i).Value = ""
        Contacts.Controls("txt" & i).BackColor = vbWhite
        Contacts.Controls("txt" & i).ForeColor = vbBlack
        Contacts.Controls("txt" & i).Visible = True
    Next i
    
    Contacts.dtaRow.Caption = lastRow - 1 & " Record"
    
    lblOrganisationName.Visible = True
    lblContactName.Visible = True
    lblTelephoneNumber.Visible = True
    lblEmailAddress.Visible = True
    lblPostalAddress.Visible = True
    lblPassword.Visible = True
    cmdbReset.Enabled = True
    cmdbChange.Enabled = True
    cmdbDelete.Enabled = True
    lb.Visible = True
    WS.Activate
    lb.RowSource = "B2:H" & lastRow
End Sub

Private Sub cmdbChange_SpinUp()
    If CurrentRow < lastRow Then
        CurrentRow = CurrentRow + 1
        UpdatecmdbChange
    Else
        CurrentRow = 2
        UpdatecmdbChange
    End If
    lb.ListIndex = CurrentRow - 2
End Sub

Private Sub cmdbChange_SpinDown()
    If CurrentRow > 2 Then
        CurrentRow = CurrentRow - 1
        UpdatecmdbChange
    Else
        CurrentRow = lastRow
        UpdatecmdbChange
    End If
    lb.ListIndex = CurrentRow - 2
End Sub

Private Sub cmdbReset_Click()
    Application.ScreenUpdating = False
    Unload Me
    Contacts.Show
    Application.ScreenUpdating = True
End Sub

Private Sub txt1_AfterUpdate()
    If Len(txt1) > 3 Then cmdbUpdate.Enabled = True
End Sub

Private Sub txt2_AfterUpdate()
    If Len(txt2) > 3 Then cmdbUpdate.Enabled = True
End Sub

Private Sub txt3_AfterUpdate()
    If Len(txt3) > 3 Then cmdbUpdate.Enabled = True
End Sub

Private Sub txt4_AfterUpdate()
    If Len(txt4) > 3 Then cmdbUpdate.Enabled = True
End Sub

Private Sub txt5_AfterUpdate()
    If Len(txt5) > 3 Then cmdbUpdate.Enabled = True
End Sub

Private Sub txt6_AfterUpdate()
    If Len(txt6) > 3 Then cmdbUpdate.Enabled = True
End Sub

Private Sub cmdbUpdate_Click()
    
    If txt1.Value = "" And txt2.Value = "" And txt3.Value = "" _
        And txt4.Value = "" And txt5.Value = "" And txt6.Value = "" Then
        MsgBox "Please update data in at least one text box.", 48, "Error"
        Exit Sub
    End If
    
    With Application
        .Calculation = xlCalculationManual
        .ScreenUpdating = False
        .DisplayStatusBar = False
        .EnableEvents = False
    End With
    
    If txt7.Visible = True Then
        cNum = 7
    Else
        cNum = 6
    End If
        
    For x = 1 To cNum
        'AlignLeft = CBool(x = 1 Or x = 7)
        With WS.Cells(CurrentRow, x + 1)
            .Value = Me.Controls("txt" & x).Value
        End With
    Next
    With Application
        .Calculation = xlCalculationAutomatic
        .ScreenUpdating = True
        .DisplayStatusBar = True
        .EnableEvents = True
    End With
    
    MsgBox "Contact modified in " & WS.Name, 64, "Success"
End Sub

Private Sub cmdbNew_Click()
    If txt1.Value = "" And txt2.Value = "" And txt3.Value = "" _
        And txt4.Value = "" And txt5.Value = "" And txt6.Value = "" Then
        MsgBox "Please enter data into at least one field.", 48, "Error"
        Exit Sub
    End If
    NextRow = WS.Cells(WS.Rows.Count, "B").End(xlUp).Row
    If Len(WS.Cells(1, 2).Value) > 0 Then NextRow = NextRow + 1
        If txt7.Visible = True Then
            cNum = 7
        Else
            cNum = 6
        End If
    For x = 1 To cNum
        AlignLeft = CBool(x = 1 Or x = 7)
        With WS.Cells(NextRow, x + 1)
            .Value = Me.Controls("txt" & x).Value
            .EntireColumn.AutoFit
            .HorizontalAlignment = IIf(x = 1 Or x = 7, xlLeft, xlCenter)
            .VerticalAlignment = xlCenter
                With .Font
                     .Name = "Arial"
                     .FontStyle = "Regular"
                     .Size = 10
                End With
        End With
        Controls("txt" & x).Text = ""
    Next
    MsgBox "Contact added to " & WS.Name, 64, "Success"
    Application.ScreenUpdating = False
    Unload Me
    Contacts.Show
    Application.ScreenUpdating = True
End Sub

Private Sub cmdbDelete_Click()
Dim smessage As String
    smessage = "Are you sure you want to delete this contact?" & vbCrLf & vbCrLf & "Name: " & txt2.Text & vbCrLf & "From: " & txt1.Text
    
    If MsgBox(smessage, vbQuestion & vbYesNo, _
              "Delete") = vbYes Then
    WS.Rows(CurrentRow).Delete
    End If
    lastRow = lastRow - 1
    lb.RowSource = "B2:H" & lastRow
End Sub

Private Sub cmdbClose_Click()
Unload Me
End Sub

Private Sub mstrYes_Click()
    txt7.Visible = True
End Sub

Private Sub mstrNo_Click()
    txt7.Visible = False
End Sub

Private Sub lb_Click()
    CurrentRow = lb.ListIndex + 2
    UpdatecmdbChange
End Sub
 
Last edited:
Upvote 0
Hello Alan, thank you for your reply. That's pretty neat, but I think the way that it works is that it prevents the search facility from searching the worksheets for the search term under the headings which are not selected.

The idea is that the user enters the search term and then can filter in real time from the data which is already showing in the existing listbox by using checkboxes (one for each column) that have a label to their left stating what they are for, it doesn't need to be within another listbox.
 
Upvote 0
Hello Alan, thank you for your reply. That's pretty neat, but I think the way that it works is that it prevents the search facility from searching the worksheets for the search term under the headings which are not selected.

The idea is that the user enters the search term and then can filter in real time from the data which is already showing in the existing listbox by using checkboxes (one for each column) that have a label to their left stating what they are for, it doesn't need to be within another listbox.

Hi Sheepdisease,
The Listbox is in place of checkboxes. The code will populate it with all unique headings from the worksheets (sorted alphabetically) and only make the search Textbox visible when at least one heading as been selected. Tjhe code will only search the selected headings data columns. Not sure how this ties in with the update tab.
 
Upvote 0
Hello Alan, thank you for your reply.

The trouble is, that does not fit in with the functionality of the userform. The user is forced to scroll through a long list of columns and pick and choose using a listbox. It does not make the best use of the space either.

I have an example of your way vs my proposed way:

yTogjiY.png


UrqAWfv.png


Also, the column headers shown should be selected/deselected after the results appear, they user shouldn't be forced to choose them before searching. The functionality you have provided is the reverse of what is required.

Does this make sense?

Amended design proposal: https://www.dropbox.com/s/co8hljozxca3div/Copy of AltBKContacts.xlsm?dl=0
 
Last edited:
Upvote 0

Forum statistics

Threads
1,224,621
Messages
6,179,929
Members
452,949
Latest member
beartooth91

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top