Whenever I try to highlight over column D I receive "Run-time error '13'". When I click debug it highlights this piece from the code, If Target.Value = "Closed" Or Target.Value = "Closed" Then. I would greatly appreciate any advice on how to fix this issue.
Edit*
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim wsd As Worksheet
Dim wsc As Worksheet
Application.ScreenUpdating = False
Set wsd = Sheets("Pipeline")
Set wsc = Sheets("Closed")
If Not Intersect(Target, Range("D6:D65536")) Is Nothing Then
If Target.Value = "Closed" Or Target.Value = "Closed" Then
erow = Target.Row
MsgBox "Moved to Closed"
numberofrow = wsc.Range("A65536").End(xlUp).Row
For i = 1 To numberofrow
If wsd.Cells(erow, 1) = wsc.Cells(i, 1) Then
Exit Sub
End If
Next
wsd.Range("A" & erow & ":A" & erow).EntireRow.Copy wsc.Range("A" & numberofrow + 1)
With Target.Parent
Union(.Range(.Cells(Target.Row, "A"), .Cells(Target.Row, "V")), _
.Range(.Cells(Target.Row, "Y"), .Cells(Target.Row, .Columns.Count))).ClearContents
`enter code here`End With
wsc.Activate
ActiveSheet.Range("A2:D" & numberofrow + 1).Select
ActiveWorkbook.Worksheets("Closed").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Closed").Sort.SortFields.Add Key:=Range("C2:C" & numberofrow + 1), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("Closed").Sort
.SetRange Range("A2:D" & numberofrow + 1)
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
wsd.Activate
End If
End If
End Sub
I had to piece a few things together in order to get this to work, which is why it's pretty ugly. I couldn't figure out where to put guard clause. This so far has worked for what I need it for (aside from the Run-time error), transferring accounts to a separate sheet based on the sales stage entered into column D. Again, I appreciate all the help.
Your handler assumes only 1 cell is selected. When you highlight an entire column, Target represents all selected cells, and then Target.Value can't be meaningfully evaluated, so it raises a run-time error.
You need to modify your handler to remove that assumption, as was suggested:
If Target.Cells.Count > 1 Then Exit Sub
Presumably that event handler needs more tweaks to verify the Target is what the macro thinks/assumes it is, but given the information you've provided that would be it.
Related
I have created a program which looks for items in Column A or Column I to change. If column I changes, it deletes and moves the row to a new sheet. If Column A changes, it should sort all of the data. However, when the second Application.Intersect(KeyCells2, Range(Target.Address)) is called, it errors out telling me I have a run-time error 424. Why is this happening? It seems to have both a key cells range and a target.address.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim KeyCells As Range
Dim KeyCells2 As Range
Dim LastRowCompleted As Long
Dim RowToDelete As Long
Dim CurCell As String
RowToDelete = 0
LastRow = Sheets("Current").Cells(Sheets("Current").Rows.Count, "A").End(xlUp).Row
LastRowCompleted = Sheets("completed").Cells(Sheets("completed").Rows.Count, "A").End(xlUp).Row
LastRowCompleted = LastRowCompleted + 1 'Next row after last row
Set KeyCells = Range("I3:I16384")
Set KeyCells2 = Range("A3:A16384")
CurCell = ActiveCell.Address
If Not Application.Intersect(KeyCells, Range(Target.Address)) Is Nothing Then
Application.EnableEvents = False
'Cut and Paste Row
Target.EntireRow.Copy Sheets("completed").Range(LastRowCompleted & ":" & LastRowCompleted)
'Mark to delete row
RowToDelete = Target.EntireRow.Row
Call DeleteRow(RowToDelete)
Application.EnableEvents = True
End If
Range(CurCell).Select
If Not Application.Intersect(KeyCells2, Range(Target.Address)) Is Nothing Then
Application.EnableEvents = False
'Sort
MsgBox "lastrow completed: " & LastRow
Range("A3:Z" & LastRow).Select
ActiveWorkbook.Worksheets("current").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("current").Sort.SortFields.Add Key:=Range("A3:A" & LastRow) _
, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("current").Sort.SortFields.Add Key:=Range("B3:B" & LastRow) _
, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("current").Sort.SortFields.Add Key:=Range("E3:E" & LastRow) _
, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("current").Sort
.SetRange Range("A3:J" & LastRow)
.Header = xlGuess
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Range(CurCell).Select
Application.EnableEvents = True
End If
End Sub
Sub DeleteRow(Row As Long)
If Row > 0 Then
Rows(Row).EntireRow.Delete Shift:=xlUp
End If
End Sub
If you delete the row in the first If block then Target no longer exists, so you can't use it in your second If block.
As a fix you could exit the Sub after deleting the row.
P.S. - that "auto-sort" seems like it would be pretty annoying if you're trying to edit data...
I am creating a code that opens another file, performs some action and closes it. In the file I am opening, there is a function that organizes the data upon closing.
I do not know how to code the filter in VBA, so I recorded a macro and pasted it into my function. The code works when I run it by itself, but when I call the main function the '.Select' doesn't appear to select the cells/columns, causing a failure.
The first function is from the first workbook, and the second is being called when the first function closes the file.
'*********First Function************
Sub AddDrawing_Button() 'activated by button in worksheet
PN = Sheets("New Drawing").Range("C5").Cells(1, 1).Value 'Part Number, D
Rev = Sheets("New Drawing").Range("C5").Cells(3, 1).Value 'Revision, E
Application.ScreenUpdating = False
Workbooks.Open ("C:\Users\Desktop\MasterDataFile.xlsm") 'Finds the file
Workbooks("MasterDataFile").Worksheets("DATA").Activate
t = Sheets("DATA").Range("D65536").End(xlUp).Row + 1 'finds the bottom row + 1
Sheets("DATA").Range("D1").Cells(t, 1).Value = PN 'Part Number, D
Sheets("DATA").Range("D1").Cells(t, 8).Value = Rev 'Revision, E
Workbooks("MasterDataFile").Close SaveChanges:=True
'upon closing this file, it jumps to the following code
Application.ScreenUpdating = True
End Sub
'*********Second Function in Second Workbook************
Sub Workbook_BeforeClose(Cancel As Boolean)
Dim ThisWs As Worksheet
Dim value1 As String
Dim value2 As String
Set ThisWs = Workbooks("MasterDataFile").Worksheets("DATA")
t = ThisWs.Range("D65536").End(xlUp).Row 'end
'Application.ScreenUpdating = False
'The following 6 lines creates a new column and populates
' each row with the part number and revision combined.
Cells(1, 24) = "Order"
For s = 2 To t
value1 = Cells(s, 4)
value2 = Cells(s, 11)
ThisWs.Cells(s, 24) = value1 + "Rev" + value2
Next s
'The following was generated by recording a macro, and uses
' the filter to organize the data. The error is occurring
' because the columns are not being selected. Why?
ThisWs.Columns("D:X").Select
Selection.AutoFilter
ThisWs.AutoFilter.Sort.SortFields.Clear
ThisWs.AutoFilter.Sort.SortFields.Add Key:=Range( _
"X1:X19519"), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
With ThisWs.AutoFilter.Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
'This turns off the filter
ThisWs.Range("A1").Select
ThisWs.Columns("D:X").Select
Selection.AutoFilter
ThisWs.Range("A1").Select
'This deletes the generated column after it has been sorted
ThisWs.Columns("X:X").ClearContents
'Application.ScreenUpdating = True
End Sub
Can someone help me understand why the cells are not being selected, with a way to fix it?
Or if all else fails, can someone post a way to filter the columns without selecting anything.
Thank you.
I have rebuilt your function, It is untested and should work, but it is not completely optimised. Everything is handled in the original function and nothing is handled in the OnClose Event.
'*********First Function************
Sub AddDrawing_Button() 'activated by button in worksheet
Dim wbMasterDataFile as Workbook
Dim shtData as Worksheet
Dim t as long
Dim s as long
'PN = Sheets("New Drawing").Range("C5").Value 'Part Number, D
'Rev = Sheets("New Drawing").Range("C7").Value 'Revision, E
Application.ScreenUpdating = False
set wbMasterDataFile = Workbooks.Open ("C:\Users\Desktop\MasterDataFile.xlsm") 'Finds the file
set shtData = wbMasterDataFile.Worksheets("DATA")
with shtData
t = .Range("D65536").End(xlUp).Row + 1 'finds the bottom row + 1
.Range("D1").Cells(t, 1).Value = Sheets("New Drawing").Range("C5").Value 'Part Number, D
.Range("K1").Cells(t, 1).Value = Sheets("New Drawing").Range("C7").Value 'Revision, E
.Cells(1, 24).Value2 = "Order"
For s = 2 To t
.Cells(s, 24) = .Cells(s, 4) + "Rev" + .Cells(s, 11)
Next s
.Columns("D:X").AutoFilter
With .AutoFilter.Sort
.SortFields.Clear
.SortFields.Add Key:=Range("X1:X19519"), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
.Columns("D:X").AutoFilter
.Columns("X:X").ClearContents
End with
set shtData = nothing
wbMasterDataFile.Close SaveChanges:=True
set wbMasterDataFile = Nothing
'upon closing this file, it jumps to the following code
Application.ScreenUpdating = True
End Sub
I have also made some more direct references to the ranges that you are using not through the Cell function
I have to run so can't explain more but will edit with more detail later.
Thank you #Bullfrog for providing me the solution to my problem, I am only posting this because I do not want other vba users to get hung up on code that may not run.
Sub AddDrawing_Button()
Dim ThisWb As Workbook, wbMasterDataFile As Workbook
Dim ThisWs As Worksheet, shtData As Worksheet
Dim t As Long, s As Long
Dim value1 As String, value2 As String
Application.ScreenUpdating = False
Set ThisWb = Workbooks("CombinationIndex")
Set ThisWs = ThisWb.Worksheets("New Drawing")
Set wbMasterDataFile = Workbooks.Open("C:\Users\Desktop\MasterDataFile.xlsm")
Set shtData = Workbooks("MasterDataFile").Worksheets("FinalDATA")
With shtData
t = .Range("D65536").End(xlUp).Row + 1 'Finds the bottom row
.Range("D1").Cells(t, 1).Value = ThisWs.Range("C5").Value 'Part Number, D
.Range("D1").Cells(t, 8).Value = ThisWs.Range("C13").Value 'Revision , E
.Cells(1, 24).value2 = "Order" 'header to new column
For s = 2 To t
value1 = .Cells(s, 4) 'originally Bullfrog's code was giving me an error due to a type mismatch
value2 = .Cells(s, 11) 'I defined a variable above, and filled it so that it was always a string
.Cells(s, 24) = value1 + "0Rev" + value2 'will use the combined values to sort data by latest rev
Next s
.Columns("D:X").AutoFilter 'using the with function to apply the filter
With .AutoFilter.Sort
.SortFields.Clear
.SortFields.Add Key:=Range("X1:X19519"), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
.Columns("D:X").AutoFilter 'Turns off the filter
.Columns("X:X").ClearContents 'deletes the data
End With
Set shtData = Nothing
wbMasterDataFile.Close SaveChanges:=True 'closes the file
Set wbMasterDataFile = Nothing
Application.ScreenUpdating = True
End Sub
I have found a similar article about my question, as stated below;
How do I track who uses my Excel spreadsheet?
However, I do like the last coloumn of comment >>
"You could also put a time stamp in the next column to show when the spreadsheet was used"
My question is> can anyone guide me the possible step or let me copy the code for doing this please? and how to hide the worksheet without anyone noticing?
My key is, very importantly, everything must done silently which no one else (other users in sharedrive) could find out i m tracking it. The reason is , i have done lot of research worksheets, and i don't have time/impossible to make every single excel worksheet perfect, i need to prioritize them inorder to be efficient with my time by knowing which one is more important to people.
many thanks~!!
In Excel, under the Review tab, you have 'Track Changes'. This should do everything you want.
If you want a VBA script to do this, try one of the following code samples.
Private Sub Worksheet_Change(ByVal Target As Range)
Set t = Target
Set a = Range("A:A")
If Intersect(t, a) Is Nothing Then Exit Sub
Application.EnableEvents = False
t.Offset(0, 7).Value = Environ("username")
Application.EnableEvents = True
End Sub
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
Dim V As Long
Application.EnableEvents = False
Set rng1 = Application.Union(Range("a1:g1"), Range("H:iv"))
Set rng = Application.Intersect(Target, rng1)
If Not rng Is Nothing Then Exit Sub
V = Target.Offset(0, 12).Value
If Target.Offset(0, 12) = "" Then
With Range("H" & Target.Row)
.Value = Target.Address & ": first entry by " & Application.UserName & " at " & Now()
.ColumnWidth = 60
.Interior.ColorIndex = 33
End With
Target.Offset(0, 12).Value = Target.Value
Application.EnableEvents = True
Exit Sub
End If
Target.Offset(0, 12).Value = Target.Value
With Range("H" & Target.Row)
.Value = Target.Address & " changed from " & V & " to " & Target.Value & " by " & Application.UserName & " at " & Now()
.ColumnWidth = 60
.Interior.Color = vbYellow
End With
Application.EnableEvents = True
End Sub
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
With Target
If .Count > 1 Then Exit Sub
If Not Intersect(Range("A2:A10"), .Cells) Is Nothing Then
Application.EnableEvents = False
Sheets("Sheet2").Select
If IsEmpty(.Value) Then
.Offset(0, 1).ClearContents
Else
With .Offset(0, 1)
.NumberFormat = "dd mmm yyyy hh:mm:ss"
.Value = Now
End With
End If
Sheets("Sheet1").Select
Application.EnableEvents = True
End If
End With
End Sub
All of these 'Worksheet_Change' scripts are worksheet events. You need to right-click your sheet and click 'View Code' then paste the script into the window that opens. Try one at a time, not all three together.
I have a spreadsheet with three columns; A B and C. Values in column C are calculated using a formula, and I want to sort Z->A on column C, expanding the selection to the other two columns as well. My goal is to have the ranking automatically updated anytime a value in column C changes. I'm looking for someone who can write this for me, I know JS but not VBA and I'm having trouble figuring it out because it's not an easy one (at least for me). Thanks!
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Column = 1 Then
Application.EnableEvents = False
Columns("C").Sort Key1:=Range("C2"), Order1:=xlDescending, _
Header:=xlGuess, OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom
Application.EnableEvents = True
End If
End Sub
=IFERROR(((ABS((((SUMIF(Orders!$B$1:$BJ$1, DATE((YEAR(TODAY())), (MONTH(TODAY())), ("<"&DAY(TODAY()))), Orders!B2:BJ2))-(SUMIF(Forecast!$B$1:$BJ$1, DATE((YEAR(TODAY())), (MONTH(TODAY())), ("<"&DAY(TODAY()))), Forecast!B2:BJ2)))/(SUMIF(Orders!$B$1:$BJ$1, DATE((YEAR(TODAY())), (MONTH(TODAY())), ("<"&DAY(TODAY()))), Orders!B2:BJ2))))*(SUMIF(Orders!$B$1:$BJ$1, DATE((YEAR(TODAY())), (MONTH(TODAY())), ("<"&DAY(TODAY()))), Orders!B2:BJ2)))/(SUMIF(Orders!$B$1:$BJ$1, DATE((YEAR(TODAY())), (MONTH(TODAY())), ("<"&DAY(TODAY()))), Orders!B2:BJ2))), 0)
Place this code in the ThisWorkbook module in the Microsoft Excel Objects folder in the VBE.
This will sort by column C in the sheet (change name in code below to suit your actual sheet) anytime the workbook is recalculated. Obviously it will happen more times than needed, but it's the only way to ensure that it fires automatically.
If you have performance issues with this because of file size or amount of "recalcs" it's possible it can be tweaked a bit, or the design of the spreadsheet can be tweaked.
Private Sub Workbook_SheetCalculate(ByVal Sh As Object)
If sh.Name = "myABCSheet" or sh.Name = "Orders" or sh.Name = "Forecast"
Dim ws As Worksheet
Set ws = Worksheets("myABCSheet") 'change name as needed
With ws
Dim lRow As Long
lRow = ws.Range("A" & ws.Rows.Count).End(xlUp).Row
With .Sort
With .SortFields
.Clear
.Add ws.Range("C1:C" & lRow), 1, xlAscending
End With
.SetRange ws.Range("A1:C" & lRow)
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
Application.Calculation = xlManual
.Apply
Application.Calculation = xlCalculationAutomatic
End With
End With
Application.EnableEvents = True
End If
End Sub
I am using the code below to sort a spreadsheet with various subtotals. On 5 out of 6 spreadsheets it works as expected. On the 6th spreadsheet I have encountered a problem with Excel ungrouping one row from a sub group. In the example below row 435 is removed from the rest of the group and row 436 has its height reduced to 0. I have looked at every cell in rows 435 and 436 and each matches the other rows in the group. After speaking with the users who would manually record a sorting macro they told me it sometimes happens to their spreadsheets as well. this macro works for the first 27 groups it has to sort. The subgroup I am having a problem with has 95 rows, other groups that have more rows do not have a problem.
Has anyone encountered this problem before and has anyone figured out how to deal with it?
The code I am using is below.
Sub mcrFindSortGroup()
Dim strFirstRow As String
Dim strLastRow As String
Dim LastCol As Integer
Dim c As Range
Dim strColumn As String
Application.DisplayAlerts = False
Application.EnableCancelKey = xlDisabled
Sheets("DCL Descriptions").Select
Range("H2:H2").Select
strColumn = ActiveCell
strColumn = strColumn - 1
Sheets("Sku Selling").Select
Columns("C:C").Select
For Each c In Range("DCL")
If c = "" Then GoTo DoneMsg
Cells(ActiveCell.Row, 1).Select
Range("C1:C15000").Activate
Selection.Find(What:=c, After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
strFirstRow = ActiveCell.Row
Cells(ActiveCell.Row, 2).Select
If Cells(ActiveCell.Row + 1, 2) <> Cells(ActiveCell.Row, 2) Then
strLastRow = ActiveCell.Row
GoTo SkipSort
End If
Range(Selection, Selection.End(xlDown)).Select
strLastRow = ActiveCell.End(xlDown).Select
strLastRow = ActiveCell.Row
RowCount = (strLastRow - strFirstRow) + 1
Rows(strFirstRow & ":" & strLastRow).Select
ActiveWorkbook.Worksheets("Sku Selling").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Sku Selling").Sort.SortFields.Add Key:=ActiveCell _
.Offset(0, strColumn).Range("A" & 1 & ":A" & RowCount) _
, SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("Sku Selling").Sort
.SetRange ActiveCell.Range("A" & 1 & ":ZZ" & RowCount)
.Header = xlGuess
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
SkipSort: ' the group has only 1 sku and does not need to be sorted
Next
DoneMsg:
MsgBox "Sorting Completed!", vbInformation, "Done"
Application.DisplayAlerts = True
Application.EnableCancelKey = xlErrorHandler
End Sub
These are before and after screen shots
Before:
After: