Good day!
I am using one of the tutorials: https://www.youtube.com/watch?v=x2_y0_KDaN0 and this is what I need with a few changes.
Here, The clients are listed in column A and the subsequent columns have dates and what interaction has been done with the client. If client xyz is in cell A2, cell b1 and onwards have dates of the months and cells b2, c2, d2 etc have either informed or pending entered. I want excel to set a reminder if the client contact is overdue beyond one week. The cells input chosen as "informed" indicates a contact that is made. I need to pick up the last date that the contact happened and calculate the dates. If the result is greater than or equal to 7, then a reminder should show. I would like to insert a column after the client name which the cell highlights and indicates a text as a reminder.
I have used the following code:
Sub dates()
End Sub
Dim x As Long
For x = 2 To informedendcolumn
Dim informedendcolumn As Integer
Dim mydate1 As Date
Dim mydate2 As Long
Dim date1 As Date
Dim date2 As Long
informedendcolumn = Range("2:2").Find(what:="informed", after:=Range("A1"), searchdirection:=xlPrevious).Column
mydate1 = Cells(informedendcolumn.ListObject.Range.Row, informedendcolumn.Column).Value
mydate2 = mydate1
date1 = Date
date2 = date1
If date2 - mydate2 = 7 Then
Cells(x, 2) = "Yes"
Cells(x, 2).Interior.ColorIndex = 3
Cells(x, 2).Font.ColorIndex = 2
Cells(x, 2).Font.Bold = True
End If
Next
End Sub
Cant really get where in going wrong. There are no errors but the code doesnt run.
Thanks in advance!
Related
In my workbook "isum", I have the week number figured out by a WEEKNUM formula (right now is week 27) listed on column X under the label Week#. The worksheet is called "Orders" with data to see what orders are late. I am struggling to create an if/then statement that makes it so that all of the week numbers on column X (starting at X2) that are < 27 (the current week number out of 52) are labeled as "Late". I am not sure how to change this value to the text, but the hard part is making sure that each week changes until it gets to 52. Otherwise nothing will change that is "Late". If this does not make sense let me know, but this is what I have so far:
isum.Sheets("Orders").Activate
Range("X2").Formula = "=WEEKNUM(RC[-9])"
Range("X2", "X" & Cells(Rows.Count, 1).End(xlUp).Row).FillDown
'Change statement to say "Late" and account for changing week numbers after every week
If cell.Value < 27 Then cell.Value = "Late"
Try looping through the range
Dim col As Range: Set col = Worksheets("Orders").Range("X2:X" & <current week num>)
Dim i As Integer
For i = 1 To col.Rows.Count
col.Cells(RowIndex:=i, ColumnIndex:="X").Value = "Late"
Next
(http://codevba.com/excel/for_each_cell_in_range.htm)
I would suggest a custom number format that displays Late for weeknums less than 27 but retains the underlying numerical weeknum value for use in future calculations. This can be applied through a conditional formatting rule that checks the weeknum formula's result against the current weeknum for dynamic results week to week.
With isum.workSheets("Orders")
With .Range(.Cells(2, "X"), .Cells(.Rows.Count, "O").End(xlUp).Offset(0, 9))
.Formula = "=weeknum(o2)"
.NumberFormat = "0_)"
.FormatConditions.Delete
With .FormatConditions.Add(Type:=xlExpression, Formula1:="=x2<weeknum(today())")
.NumberFormat = "L\at\e_)"
'optionally apply a red fill color
'.interior.color = vbred
End With
End With
End With
I hope you can help. I have a small piece of code below. The issue I am having is that I am trying to subtract today's date from the date in Column C (see Pic 1) and then return a numerical result in Column D and then continue this formula down Column D until there is no values left in column C to subtract against.
So today's date is 09/03/2017 I want to subtract this date from the date in C2 03/07/2017 giving me 2 in D2 and then continue this through column D until C has a blank cell.
The piece of code that is bugging is Range("D2").Formula = DateDiff(C2, Date, "d")
The error I get is run time error 13 type mismatch.
The larger piece of code it belongs to is
Public Sub Activate_Sheet()
Worksheets("In Progress").Activate
Columns.AutoFit
Range("N:N").EntireColumn.Delete
Range("D1").Value = "# days open"
Range("D2").Formula = DateDiff(C2, Date, "d")
End Sub
As always any and all help is greatly appreciated.
Pic 1
Instead of
Range("D2").Formula = DateDiff(C2, Date, "d")
use
Range("D2").Formula = "=DAYS(TODAY(),C7)"
.Formula has to be a formula as you write it into a cell (for english Excel versions). If you have a non-english (localized) Excel version then you can use .FormulaLocal to write formulas in your localized language.
DateDiff function Parameters:
Interval in your case "d" (represnting days), is the first parameter, not the third.
You can't use C2 inside the DateDiff function, but you need to get the value from that cell by using Range("C2").Value.
Also, DateDiff will return a Numeric result in days, so you need to enter it in Range("D2").Value and not Formula.
Modify your code to:
Range("D2").Value = DateDiff("d", Range("C2").Value , Date)
Edit 1: To run this code for all occupied cells in Column C:
Dim LastRow As Long, i As Long
With Worksheets("In Progress")
LastRow = .Cells(.Rows.Count, "C").End(xlUp).Row
For i = 2 To LastRow
.Range("D" & i).Value = DateDiff("d", .Range("C" & i).Value, Date)
Next i
End With
I have a column of data (C) that has many cells that contain dates. I am trying to create a macro that checks to see if each cell contains a date and if it does then advance the date on month. I have the code to advance the date one month from here http://excel.tips.net/T002180_Automatically_Advancing_by_a_Month.html and it works fine but I am not sure how to replace the range with a dynamic range that evaluates all cells in column C. If possible I would also like to eliminate the need for a loop. Here is what I have so far.
Sub IncreaseMonth()
Dim dDate As Date
Dim NumberofTasks As Integer
NumberofTasks = ThisWorkbook.Worksheets("Dashboard").Range("Number_of_Tasks")
Dim x As Integer
For x = 1 To NumberofTasks
dDate = Range("C30").Value
Range("C30").Value = _
DateSerial(Year(dDate), _
Month(dDate) + 1, Day(dDate))
Next x
End Sub
Try something like the code below (I use DateAdd function to add 1 Month to the current date value)
Sub IncreaseMonth()
Dim dDate As Date
Dim NumberofTasks As Long
Dim x As Long
With Worksheets("Dashboard")
' I suspect you want to get the last row with data in Column C
NumberofTasks = .Cells(.Rows.Count, "C").End(xlUp).Row
For x = 1 To NumberofTasks
If IsDate(.Range("C" & x).Value) Then '<-- check if current cell at Column C is Date
.Range("C" & x).Value = DateAdd("m", 1, .Range("C" & x).Value) '<-- add 1 Month to current date in Column c, use DateAdd function
End If
Next x
End With
End Sub
This snippet should put you on the right track. I'm making a couple of assumptions here. The first is that you have a named range called "Number_of_Tasks" on which you wish to operate. Second is that all values in this range are a valid date. If values could be an invalid date (like a blank) you should check for this before setting the value.
You will also wish to ensure that the month does not become invalid. Incrementing the month past December will not be a valid date.
Sub IncreaseMonth()
Dim tempCell As Range
For Each tempCell In ThisWorkbook.Worksheets("Dashboard").Range("Number_of_Tasks")
tempCell.Value = DateSerial(Year(tempCell.value), Month(tempCell.value) + 1, Day(tempCell.value))
Next tempCell
In an earlier post "User3598756" provided the code/solution to my inquiry on how to extract from multiple sheets to multiple sheets and I'm extremely thankful for the help.
Now I'd need to pull data by month, so I attempted to modify the below code hoping that when a new command button is clicked it pulls from each of the six sheets based on an entered begin/end date BUT extracts the data from specific columns only and transfers the results to a master sheet destination. BUT I apparently am not doing something correctly in the code I've tried to modify:
Private Sub cmdRunMonthlyRpt_Click()
Dim startdate As Date, enddate As Date
Dim rng As Range, c As Range
Dim destRow(1) As Long
Dim shtSrc(1 To 6) As Worksheet
Dim shtDest(1) As Worksheet
Dim i As Long
Set shtSrc(1) = Sheets("Recruiter")
Set shtSrc(2) = Sheets("SrRecruiter")
Set shtSrc(3) = Sheets("RecruiterSpc")
Set shtSrc(4) = Sheets("SrOfcSpc")
Set shtSrc(5) = Sheets("SrOfcSpcB")
Set shtSrc(6) = Sheets("UnivRecruiter")
Set shtDest(1) = Sheets("Extract_Scorecard_Month")
destRow(1) = 2
startdate = CDate(InputBox("Input desired start date for report data"))
enddate = CDate(InputBox("Input desired end date for report data"))
For i = 1 To 6
Set rng = shtSrc(i).Range("A:A").SpecialCells(xlCellTypeConstants, xlNumbers) 'this will select only numbers constants. since dates are numbers they'll get into this range
For Each c In rng
If c.Value >= startdate And c.Value <= enddate Then
c.Offset(0, 0).Resize(1, 45).Copy Destination:=shtDest(i).Cells(destRow(i), 1)
destRow(i) = destRow(i) + 1
End If
Next c
Next i
End Sub
I think I am making things harder than needed, so if there's a better way to accomplish the desired output, I'd appreciate some instruction. I am an Administrative Assistant trying to learn VBA.
Thank you
The below mentioned data is for door access in a company where in we need to find the number of hours spent by a employee in office.
A employee can come in the office and swipe in and swipe out multiple times and all these details are register in the excel in non sorted order for all the employees.
I have a excel containing multiple columns
First two columns A,B are merged cells having date in this format(2015/01/25 7:27:30 PM).
The third column C has Access information having multiple entries for the below values(Entry/Exit).
For example
Column A Column B Access Employee ID Employee Name
==================================================
1. 2015/01/25 7:27:30 AM Entry 111 XYZ
2. 2015/01/25 7:30:30 AM Entry 333 ABC
3. 2015/01/25 8:30:30 AM Exit 111 XYZ
4. 2015/01/25 9:30:30 AM Entry 111 XYZ
5. 2015/01/25 9:30:30 AM Entry 444 PQR
6. 2015/01/25 10:30:30 Pm Exit 333 ABC
7. 2015/01/26 7:30:30 AM Exit 333 ABC
And so on.
Please note that the same employee can have multiple swipe in and out's throughout the day and will be clobbered among other employees information
The Goal is to as below
1) Copy the data from one sheet to another for the employees having spent time less than 9 hours for a specific day.
Here is the sample code that i have written it is work in progress
Sub HoursList()
Dim cell As Range
Dim cell1 As Range
Dim NewRange As Range
Dim NewRange1 As Range
Dim MyCount As Long
Dim ExistCount As Long
Dim ExistsCount As Boolean
Dim temp As Long
Dim MyCount1 As Long
Dim wsh As Worksheet, i As Long, lngEndRowInv As Long
Set wsh = Worksheets("Standard Door History ")
'Set cell = Range("A1")
ExistCount = 0
ExitsCount = False
MyCount = 1
MyCount1 = 1
i = 12
lngEndRowInv = wsh.Range("P" & wsh.Rows.Count).End(xlUp).Row
'----For every cell in row G on the Data sheet----'
For Each cell In wsh.Range("C12:D9085")
If cell.Value = "Entry" Then
'ExistCount = ExistCount + 1
If MyCount = 1 Then Set NewRange = cell.Offset(0, -1)
'----Sets up a new range to copy all data from the row if column in that row contains the value in question----'
Set NewRange = Application.Union(NewRange, cell.EntireRow)
MyCount = MyCount + 1
End If
Next cell
For Each cell1 In NewRange
If cell1.Value = "Mayur" Then
If MyCount1 = 1 Then Set NewRange1 = cell.Offset(0, -1)
'----Sets up a new range to copy all data from the row if column in that row contains the value in question----'
Set NewRange1 = Application.Union(NewRange1, cell.EntireRow)
MyCount1 = MyCount1 + 1
End If
Next cell1
If ExistCount > 0 Then
NewRange.Copy Destination:=Worksheets("Test").Range("A3")
End If
End Sub
Thanks
Here is a very rough version that you could use in VBA. It needs refining and error trapping, and future proofing, but it does what you want it to. It takes data from the active sheet and current adds it to the second worksheet. The date for looking up is in cell N1 of the first sheet.
Option Explicit
Sub CopyNine()
Dim LastRow As Integer
Dim DateToFind As Variant
Dim CellDate As Variant
Dim Count As Integer
Dim cel As Range
Dim DateRange As Range
Dim StaffID As String
Dim TimeStamp As Double
Dim StaffSummary As Object
Dim DS As Worksheet
Dim SS As Worksheet
Dim SSRow As Integer
LastRow = Range("A1").End(xlDown).Row
'You may wish to turn this into an input instead
DateToFind = Range("N1").Formula
Set DS = ActiveSheet
'You may wish to change this
Set SS = Sheets(2)
SSRow = 2
'Get a range containing all the correctly dated cells from the dataset
For Each cel In Range("A2:A" & LastRow).Cells
CellDate = Left(cel.Formula, InStr(1, cel.Formula, ".") - 1)
If CellDate = DateToFind Then
If DateRange Is Nothing Then
Set DateRange = cel
Else
Set DateRange = Union(DateRange, cel)
End If
End If
Next
'Create a summary dictionary of all staff IDs and their time spent in the office where 1 = 1 day
Set StaffSummary = CreateObject("scripting.dictionary")
For Each cel In DateRange.Cells
StaffID = cel.Offset(0, 3).Value
'These may need to be updated depending on your entry in the 'Entry/Exit' column
If cel.Offset(0, 2).Value = "Entry" Then
TimeStamp = -cel.Formula
Else
TimeStamp = cel.Formula
End If
If Not StaffSummary.exists(StaffID) Then
StaffSummary.Add StaffID, TimeStamp
Else
StaffSummary.Item(StaffID) = StaffSummary.Item(StaffID) + TimeStamp
End If
Next
'Copy the titles from the data sheet
SS.Range("A1:E1").Value = DS.Range("A1:E1").Value
'Copy the appropriate rows across using the dictionary you created
For Each cel In DateRange.Cells
StaffID = cel.Offset(0, 3).Value
If StaffSummary.Item(StaffID) <= 9 / 24 Then 'This is 9 hours so copy across
SS.Range("A" & SSRow & ":E" & SSRow).Value = DS.Range(cel, cel.Offset(0, 4)).Value
SSRow = SSRow + 1
End If
Next
End Sub
I would suggest using Excel's inbuilt abilities before VBA, especially if you are new to VBA. This will involve adding additional columns to your input sheet though which you can hide, but may not be ideal for your situation. It could also get quite slow as there are some large calculations, but it does depend on your original data set.
I would suggest the following (although there will be a lot of variations on it!):
1) Create a summary table for the particular day.
Create a date column in column F which is =TRUNC(A2) and copy down the table.
In M1 have your input date - e.g. 2015/01/25
In column L list all the unique Staff IDs
Below the date in M, use a SUMIFS formula and time formatting to determine how many hours each person spent. In M3 for example =SUMIFS($A:$A,$D:$D,$L2,$C:$C,"Exit",$F:$F,$M$1) - SUMIFS($A:$A,$D:$D,$L2,$C:$C,"Entry",$F:$F,$M$1) then formatting as hh:mm:ss.
In column N, use =M2<TIME(9,0,0) and drag down to work out if that individual has spent less than 9 hours in the building on that day.
You should now have a table showing all the staff and how many hours they spent in the building on that day, and a TRUE or FALSE whether they spent less than 9 hours.
2) Create your additional columns to pull the data to another sheet
In Column G, determine whether the entry is for the date in question (in cell M1) using =F2=$M$1 (should give a TRUE or FALSE)
In Column H, determine if that individual has spent less than 9 hours (from the summary table) using =INDEX(N:N, MATCH(D2, L:L,0))
In Column I, determine whether that entry should be copied across using =AND(G2, H2)
Finally in Column J, determine which entry this is to copy across using `=IF(I2, COUNTIFS($I$1:I2,TRUE),"")
Copy each of these down to the bottom of the table (you can hide them later)
3) Create your table on the next sheet for copying down - I have called my original worksheet "Data" and my second one "Copy"
In column A, use =ROW()-1 to create a sequential list of numbers
In column B, use =MATCH(A2, Data!J:J,0) to find out which row of data from the original table is being copied across
In column C, use =IFERROR(INDEX(Data!A:A,$B2),"") to pull the data from the first column
Copy this formula across to column G
Copy all of these down the sheet to however many rows of data you would like
Hide columns A, B and D since these will contain irrelevant information
You should then have an autoupdating table based on the date in cell M1 on the original data sheet. As mentioned above, this can be adapted in many ways, and it may not be ideal for your situation depending on your data set size, but it may be a start for you. If it is not suitable, then please use the theory to adapt some VBA code, as this can also be done in VBA in a very similar way.