Sort dialog box lock data headers vba - vba

All,
I am using some code to bring up the sort dialog box via VBA. My data set will always have a header and I want to lock "My data has headers button in the corner of the sort dialog box"
I have inserted the line
`ActiveSheet.Sort.Header = xlYes`
However this does not seem to be acting in the way I would expect it to. The result I wish to obtain is within the screen shot below;
Full code below;
Sub ShowSortDialogBRR()
Application.ScreenUpdating = False
Application.Calculation = xlManual
ActiveSheet.Unprotect Password:="fsp123"
Application.EnableEvents = False
'select range and show sort dialog box
Dim Lastrow As Long
Lastrow = ActiveSheet.Range("LastRow_BRR").Offset(rowOffset:=-1).Row
Brr.Range("B3:CE" & Lastrow).Select
On Error Resume Next
ActiveSheet.Sort.Header = xlYes
Application.Dialogs(xlDialogSort).Show
If Err.Number = 1004 Then
MsgBox "Place the cursor in the area to be sorted"
End If
Err.Clear
With ActiveSheet
.Protect Password:="fsp123", UserInterfaceOnly:=True, DrawingObjects:=False, Contents:=True, AllowFiltering:=True, AllowFormattingColumns:=True
.EnableOutlining = True
End With
Application.ScreenUpdating = True
Application.Calculation = xlAutomatic
Application.EnableEvents = True
End Sub
any help to resolve this matter would be much appreciated.

That option is grayed out when the range has a filter applied. You don't have to actually filter the data, just have filter dropdowns showing. Here's an example that turns on the fitlers if they're not already.
Sub SortData()
Dim r As Range
Dim HasFilter As Boolean
Set r = Sheet1.Range("A1:B4")
HasFilter = Sheet1.AutoFilterMode
If Not HasFilter Then
r.AutoFilter
End If
Application.Dialogs(xlDialogSort).Show
If Not HasFilter Then
r.AutoFilter
End If
End Sub

Related

Automation Error - Unspecified Error (Runtime Error -2147467259)

I need some help. I am new to Excel VBA. I am trying to create a userform for stock inventory records and I been geting the automation error -2147467259. My problem is that the code works but after a few mouse clicks (10 or more) or after long usage, I keep getting this error. My code:
Private Sub cbPickID_Change()
Application.ScreenUpdating = False
Application.EnableEvents = False
Dim tbl_issuance As ListObject
Set tbl_issuance = shIssuance.ListObjects("tblIssuance")
If Not tbl_issuance.DataBodyRange Is Nothing Then
tbl_issuance.DataBodyRange.Delete
End If
Dim tbl_pick As ListObject
Set tbl_pick = shPickList.ListObjects("tblPickList")
On Error GoTo ErrDetect
With tbl_pick.DataBodyRange
.AutoFilter field:=1, Criteria1:=Me.cbPickID.Value
End With
Dim pick_row As Long
pick_row = shPickList.Range("A" & Application.Rows.Count).End(xlUp).Row
shPickList.Range("A3:L" & pick_row).SpecialCells(xlCellTypeVisible).Copy
shIssuance.Range("A3").PasteSpecial (xlPasteValuesAndNumberFormats)
tbl_pick.AutoFilter.ShowAllData
Application.CutCopyMode = False
Dim issued_row As Long
issued_row = shIssuance.Range("A" & Application.Rows.Count).End(xlUp).Row
With Me.lbPickList
.ColumnHeads = True
.ColumnCount = 12
.ColumnWidths = ("40,40,40,110,0,45,40,60,90,0,0,0")
.RowSource = shIssuance.Range("A3:L" & issued_row).Address
End With
ErrDetect:
If Err.Number = 1004 Then
MsgBox "No records found!"
Exit Sub
End If
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
When I click debug, the error point at this
tbl_issuance.DataBodyRange.Delete
all my reference are in the same file. if I want to use the Excel VBA again, I need to close all Excel file and re-open them again.
any advice is highly appreciated.

How to leave an edited-empty cell unlocked when sheet protection is initiated after an event

I would like to lock cells in a worksheet when data is entered. Also, the administrator would have access to unprotect the worksheet when changes have to be made. But with this code I have the following issues:
When data is entered and then the sheet it unprotected for deleting the data, the code then is unable to allow rentry of data into the same cells from where data was deleted, is there a good method to enable this?
I have tried a few options that relate to Target.Cells, ActiveSheet.UsedRange, ActiveSHeet.OnEntry and Application.OnKey but nothing seems to override the delete/baackspace event.
Any help would be appreciated. This is the current code:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim ToLock As String
Dim R As Range
Application.ScreenUpdating = False
ToLock = MsgBox("This input will now be locked.", vbOKCancel, "Confirm Change")
''If locking is accepted
If ToLock <> vbOK Then
Application.EnableEvents = False
Target.ClearContents
Application.EnableEvents = True
Exit Sub
End If
''Once entry entered, sheet will be locked with this password
ActiveSheet.Unprotect "quality"
' For Each R In ActiveSheet.UsedRange
For Each R In Target.Cells
If R.Value <> "" Then
Target.Locked = True
End If
Next R
ActiveSheet.Protect Password:="quality", DrawingObjects:=True, Contents:=True, Scenarios:=True
Application.ScreenUpdating = True
End Sub
Try this:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rnCell As Range, rnEmpty As Range
On Error Resume Next
Set rnEmpty = emptyCells(Target)
If Not (rnEmpty Is Nothing) Then
If rnEmpty.Address = Target.Address Then Exit Sub
End If
Application.ScreenUpdating = False
Application.EnableEvents = False
On Error GoTo ChangeEnd
If MsgBox("This input will now be locked.", vbOKCancel, "Confirm Change") = vbCancel Then
Target.ClearContents
GoTo ChangeEnd
End If
ActiveSheet.Unprotect "quality"
Target.Locked = True
Set rnEmpty = emptyCells(ActiveSheet.UsedRange)
If Not (rnEmpty Is Nothing) Then rnEmpty.Locked = False
ChangeEnd:
ActiveSheet.Protect Password:="quality", DrawingObjects:=True, Contents:=True, Scenarios:=True
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
Private Function emptyCells(rnIn As Range) As Range
On Error Resume Next
If rnIn.Cells.Count = 1 Then
If (rnIn.Value = vbNullString) And (rnIn.Formula = vbNullString) Then
Set emptyCells = rnIn
End If
Else
Set emptyCells = rnIn.SpecialCells(Type:=xlCellTypeBlanks)
End If
End Function
Some changes were introduced for readability, some others to fit functionality you seek for, others to avoid looping. Hope that helps... any questions, please comment and will add explanation.
It should work when you paste ranges (empty cells will still be editable)

Faster multiple criteria search/filter excel

Hi guys I made the code below to search for multiple text in a given column. The problem is that it is very slow. Do guys know any other ways to perform it faster?
For example give the array ('foo', 'bar'), The code should iterate on a column and match/filter only the rows that have both texts in any given order.
Sub aTest()
ScreenUpdating = False
Dim selectedRange As Range, cell As Range
Dim searchValues() As String
searchValues = Split(ActiveSheet.Cells(2, 1).Value)
Set selectedRange = Range("A4:A40000")
Dim element As Variant
For Each cell In selectedRange
If cell.Value = "" Then
Exit For
Else
For Each element In searchValues
If Not InStr(1, cell.Value, element) Then
cell.EntireRow.Hidden = True
End If
Next element
End If
Next cell
ScreenUpdating = True
End Sub
I was using it as a filter. copied and pasted the following code with a few modifications. But then I was not able to make the changes to match multiple strings.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim iFilterColumn As Integer
Dim rFilter As Range
Dim sCriteria As String
On Error Resume Next
With Target
Set rFilter = .Parent.AutoFilter.Range
iFilterColumn = .Column + 1 - rFilter.Columns(1).Column
If Intersect(Target, Range("rCriteria")) Is Nothing Then GoTo Terminator
Select Case Left(.Value, 1)
Case ">", "<"
sCriteria = .Value
Case Else
sCriteria = "=*" & .Value & "*"
End Select
If sCriteria = "=" Then
.Parent.Range(rFilter.Address).AutoFilter Field:=iFilterColumn
Else
.Parent.Range(rFilter.Address).AutoFilter Field:=iFilterColumn, Criteria1:=sCriteria
End If
End With
Terminator:
Set rFilter = Nothing
On Error GoTo 0
End Sub
I'm assuming this:
Set selectedRange = Range("A4:A40000")
It's because the size is not defined properly, the following should limit to the right long
Set selectedRange = Range("A4:A" & Cells(Rows.Count, "A").End(xlUp).Row)
If it doesn't affect, I always use these codes to speed up Excel (Instead of only ScreenUpdating alone).
Sub ExcelNormal()
With Excel.Application
.Cursor = xlDefault
.ScreenUpdating = True
.DisplayAlerts = True
.Calculation = xlCalculationAutomatic
.StatusBar = False
End With
End Sub
Sub ExcelBusy()
With Excel.Application
.Cursor = xlWait
.ScreenUpdating = False
.DisplayAlerts = False
.Calculation = xlCalculationManual
.StatusBar = False
End With
End Sub
Note: In the future Probably Code Review would be better place to post.

Why is this "Delete Method of Range class failed" error popping up?

I am trying to figure out why this "Delete Method of Range Class" error is popping up. It does not always occur when this macro runs, which makes it all the more perplexing.
Can anybody explain this?
Sub ResetSheet()
If WindowsOS Then
'*******************************************************************************************************'
'Resets the Data sheet. Called by the resetSheetButton procedure (located in module: m7_Macros1_5). '
'Also called by the OkCommandButton_Click procedure in the OnOpenUserForm form. '
'*******************************************************************************************************'
Application.EnableEvents = False
Sheet4.Visible = True
Sheet4.Activate
Sheet4.Select
Sheet4.Rows("2:101").Select
Selection.Copy
'TC Edit
Sheet1.Activate
Sheet1.Range("A2").PasteSpecial (xlPasteAll)
'Sheet1.Paste
Sheets("Data").Select
Sheet1.Rows("102:10000").EntireRow.Delete
Sheet4.Visible = False
'TC Edit 2.0 - Adding code to reset the exception checkboxes
If WindowsOS Then
Call resetCheckBoxes
End If
Application.EnableEvents = True
This is the macro code that causes the error (sometimes)
This is the error pop-up
try with below simplified code
Sub ResetSheet()
'If WindowsOS Then
Application.EnableEvents = False
With Worksheets("Sheet4")
.Visible = True
.Rows("2:101").Copy Worksheets("Sheet1").Range("A2")
End With
With Worksheets("Sheet1")
.Rows("102:101").EntireRow.Delete
End With
Worksheets("Sheet4").Visible = False
If windowsOS Then
Call resetCheckBoxes
End If
Application.EnableEvents = True
End Sub

vba for cut and paste is too slow

I have two protected sheets:
Customer Stock
Collected Stock
Once a customer collects the stock, I trigger column (G:CustomerRow) in Customer Stock Sheet and it automatically cuts and paste above the first row (“2:2”) in the Collected Stock Sheet.
The problem is the VBA code takes too long to do that.
Somebody told my code has to be edited to avoid things like too many .selects etc.
Can somebody help me to modify my code to speed up the cut paste macro?
All I need is a macro for removing one row and pasting its values to another sheet above row ("2:2")
In the Customer Stock Sheet, the code is:
Private Sub Worksheet_Change(ByVal Target As Range)
On Error Resume Next
If Target.Column = Columns(7).Column Then 'where G is the seventh column
If Target.Value <> "" Then
Call CustomerCollected
End If
End If
End Sub
In the module:
Sub CustomerCollected()
Dim actCell
actCell = Range("G" & ActiveCell.Row)
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.DisplayStatusBar = False
Application.EnableEvents = False
ActiveSheet.DisplayPageBreaks = False
Response = MsgBox("Do you want to transfer this Customer from Customer Stock to Collected Stock?", vbYesNo)
If Response <> 6 Then
Exit Sub
End If
If Response = 6 Then
Worksheets("Collected Stock").Unprotect Password:="a27826" ' change the password to whatever you wish
If actCell <= Date Then
Rows(ActiveCell.Row).Select
Selection.Cut
Sheets("Collected Stock").Select
Rows("2:2").Select
Selection.Insert Shift:=xlDown
Range("A1").Select
Sheets("Customer Stock").Select
Selection.EntireRow.Delete
Range("A1").Select
End If
Worksheets("Collected Stock").Protect Password:="a27826", _
DrawingObjects:=True, _
Contents:=True, _
Scenarios:=True, _
UserInterfaceOnly:=True, _
AllowFormattingCells:=False, _
AllowFormattingColumns:=False, _
AllowFormattingRows:=False, _
AllowInsertingColumns:=False, _
AllowInsertingRows:=False, _
AllowInsertingHyperlinks:=False, _
AllowDeletingColumns:=False, _
AllowDeletingRows:=False, _
AllowSorting:=False, _
AllowFiltering:=False, _
AllowUsingPivotTables:=False
End If
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.DisplayAlerts = True
Application.DisplayStatusBar = True
Application.EnableEvents = True
ActiveSheet.DisplayPageBreaks = True
End Sub
You hardly ever need to use .Select for anything - you can access an objects properties directly without selecting it first. i.e. :
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Column = 7 And Target.Value <> "" Then
Application.EnableEvents = False '// Prevent infinite loop
CustomerCollected
Application.EnableEvents = True '// Re-enable events
End If
End Sub
and
Sub CustomerCollected()
'// Check user wants to transfer row, if no then exit
If MsgBox("Do you want to transfer this Customer from Customer Stock to Collected Stock?", vbYesNo) = vbNo Then Exit Sub
'// Cut active row and insert into other workbook
ActiveCell.EntireRow.Cut
With Sheets("Collected Stock")
.Unprotect "a27826"
.Rows(2).EntireRow.Insert Shift:=xlDown
.Protect "a27826"
End With
ActiveCell.EntireRow.Delete Shift:=xlUp
Application.CutCopyMode = False
End Sub