I have the below code to open up files with variable file names, due to dates being in them. I personally save each file daily with the date stamp, ie this morning I saved a file with yesterday's date, 4.20.17.
This code will be run every Friday morning, and the goal is to load the last 5 work days' files (last Friday, this Monday, Tues, Wed, Thurs) grab some info out of those files (copy 2 cells from each), paste that info in a new sheet, and finally close each file.
Currently, the code is set to tell me when a file does not exist (for instance, last Friday was Good Friday, so Monday morning, I did not create any file for last Friday), and then ignore and move past that day.
The issue I currently have (besides the code being long and can probably be concatenated) is that a file exists for last Thursday, yet my code tells me there is none. I have been advised that this is because the code is actually looking at today (Thursday) and not a week ago Thursday, where there actually is a file.
Any assistance is appreciated. I removed a few days to make the below code less of a bear to look at, and a sample filename is "Agent Group Daily Summary 4.19.17"
Const strFilePath As String = "D:\Users\stefan.bagnato\Desktop\Daily Performance Summary\Agent Group Daily Summary "
Dim LastFridayDate, MondayDate, TuesdayDate, WednesdayDate, ThursdayDate As String
Dim fullFileNameLastFriday, fullFileNameMonday, fullFileNameTuesday, fullFileNameWednesday, fullFileNameThursday As String
Dim wbkLastFriday, wbkMonday, wbkTuesday, wbkWednesday, wbkThursdayOpen As Workbook
LastFridayDate = Format(Date - (Weekday(Date, vbFriday) - 1), "m.d.yy")
fullFileNameLastFriday = strFilePath & LastFridayDate & ".xls"
If Dir(fullFileNameLastFriday) = "" Then
MsgBox "File for last Friday doesn't exist!"
GoTo ExitLastFriday
End If
Set wbkLastFriday = Workbooks.Open(fullFileNameLastFriday, False, True)
Call BasicDailySummary
wbkLastFriday.Activate
Range("T2:T8").Copy
fp.Activate
Range("B3:B9").PasteSpecial xlPasteValues
wbkLastFriday.Activate
Range("F2:F8").Copy
fp.Activate
Range("G3:G9").PasteSpecial xlPasteValues
wbkLastFriday.Close SaveChanges:=False
ExitLastFriday:
MondayDate = Format(Date - (Weekday(Date, vbMonday) - 1), "m.d.yy")
fullFileNameMonday = strFilePath & MondayDate & ".xls"
If Dir(fullFileNameMonday) = "" Then
MsgBox "File for Monday doesn't exist!"
GoTo ExitMonday
End If
Set wbkMonday = Workbooks.Open(fullFileNameMonday, False, True)
Call BasicDailySummary
wbkMonday.Activate
Range("T2:T8").Copy
fp.Activate
Range("C3:C9").PasteSpecial xlPasteValues
wbkMonday.Activate
Range("F2:F8").Copy
fp.Activate
Range("H3:H9").PasteSpecial xlPasteValues
wbkMonday.Close SaveChanges:=False
ExitMonday:
....................................
ThursdayDate = Format(Date - (Weekday(Date, vbThursday) - 1), "m.d.yy")
fullFileNameThursday = strFilePath & ThursdayDate & ".xls"
If Dir(fullFileNameThursday) = "" Then
MsgBox "File for Thursday doesn't exist!"
GoTo ExitThursday
End If
Set wbkThursday = Workbooks.Open(fullFileNameThursday, False, True)
Call BasicDailySummary
wbkThursday.Activate
Range("T2:T8").Copy
fp.Activate
Range("F3:F9").PasteSpecial xlPasteValues
wbkThursday.Activate
Range("F2:F8").Copy
fp.Activate
Range("K3:K9").PasteSpecial xlPasteValues
wbkThursday.Close SaveChanges:=False
ExitThursday:
That a file exists for last Thursday, yet my code tells me there is none
As I explained in the other question you asked yesterday, putting the vbMonday or vbThursday etc in the Format function doesn't magically tell VBA to return that day:
Hint: The vbFriday part of the Weekday function is not magically telling it to get friday's date. It's actually telling it that, for the sake of this function call, consider Friday to be the first day of the week. The Weekday function then returns an integer (the ordinal day of the week) which it subtracts from the Date.
So, you need to go back and understand how those functions work, you can't just dump constants in there willy-nilly without making an effort to understand what they're doing, or why. On that note, you absolutely need to read this and learn how to begin debugging and troubleshooting first. This describes basics of how to step through your code and examine variable's values/etc at runtime. These techniques are foundations you need to work with VBA.
Here is a list of statements available in VBA. This is documentation that explains things like "How to create a loop structure with For/Next, etc."
And you should go back through the dozen or so questions you've asked here, and mark accepted answers for those where an answer has solved your problem. This is just a basic point of etiquette: You've asked 11 questions here and only accepted 1 answer.
Note also that this sort of declaration does not do what you think it does:
Dim LastFridayDate, MondayDate, TuesdayDate, WednesdayDate, ThursdayDate As String
Dim fullFileNameLastFriday, fullFileNameMonday, fullFileNameTuesday, fullFileNameWednesday, fullFileNameThursday As String
Dim wbkLastFriday, wbkMonday, wbkTuesday, wbkWednesday, wbkThursdayOpen As Workbook
Only the last item in each of those statements are strongly typed, the rest are implicitly variant. You should strongly type all variables when possible, e.g.:
Dim wbkLastFriday As Workbook, wbkMonday As Workbook, wbkTuesday As Workbook, wbkWednesday As Workbook, wbkThursdayOpen As Workbook
And rather than using five different workbook objects (unless you really need 5 workbooks open at once, just use a single workbook object and operate within a loop, opening successive file at each iteration.
Dim wb as Workbook
Dim i as Long
For i = 1 to 5
Set wb = Workbooks.Open(...)
'Do something
wb.Close()
Next
Getting to your actual problem:
A function like below will return an array of your date components. This returns the previous 7 days from the FirstDay (which defaults to Friday previous). You can use the Dir function as previously to simply test whether a filename is valid/existing (e.g., Sunday file doesn't exist, etc.), and skip over it if it's not valid.
Function GetFileNames(Optional FirstDay = vbFriday)
Dim filenames(1 To 7) As String
Dim i As Long
For i = 1 To 7
filenames(i) = Format(Date - (Weekday(Date, FirstDay) + i), "m.d.yy")
Next
GetFileNames = filenames
End Function
It seems that you want your search to start from yesterday instead of today. If so, you can try changing
ThursdayDate = Format(Date - (Weekday(Date, vbThursday) - 1), "m.d.yy")
into
ThursdayDate = Format(Date - (Weekday(Date - 1, vbThursday)), "m.d.yy")
and generalize it to other week days. In fact what it does now is that when it runs, say, on this Thursday, it looks up for the file of last Thursday...
Related
so I need a macro code for naming a worksheet with the next date on it, as in if the previous sheet is called Tue 27 then the next sheet (new one) should be Wed 28,
my current code only names it as TODAYS date, this is what I am using
Dim szTodayDate As String
szTodayDate = Format(Date, "ddd") & Format(Date, " dd")
On Error GoTo MakeSheet
Sheets(szTodayDate).Activate
Exit Sub
MakeSheet:
Dim Srt As Worksheet
Set Srt = ActiveSheet
Sheets.Add
ActiveSheet.Name = szTodayDate
Is it even possible to do this, and if so, can anyone please tell me how,
Thank you
additional note: so the macro creates a new sheet everytime I run it, and then names it with todays date, I need it instead to name it with the NEXT date, in relation to the previous sheet. so if the last sheet made (prior to macro run) is called "Sun 02" the macro should create a sheet and name it "Mon 03", assume for now that the month doesn't matter, I will not run this macro after the month ends, so on workbook Feb, "Wed 28" would be the last time I run this macro.
Reason Explained: so I need to create a new worksheet everyday for work, but I sometimes end up having to make the worksheet a day later, so lets say on sun 02 I make the sheet on time, so now I have worksheet sun 02, but then I miss it on monday, then on tuesday I make the sheet, it ends up making Sheet Tue 04, so now I'm missing Mon 03.
Possible Alternate: If I could somehow set an IF function that can check to see if worksheet with yesterdays name exists (maybe going back upto 2 days) and if not create it, that would work to. but not sure how to code said IF function either (It would also need to create it and name it as today, if today is 01).
Thank you again
An important note for the following code: in its default state it requires that the Sheet Names include the Month, so the format is "ddd dd mmm" ("Wed 28 Feb") not "ddd dd" ("Wed 28"). If, for example, the Month is stored in the FileName instead then you will need to modify the code.
We need a variable to store the most recent date found, and a Worksheet object to use in a For Each loop. We will check each Worksheet's Name and check if it IsDate. If it is, then we will see if it is later than our currently stored Date. This will fail at year end, unless you start including the Year in the Sheet Name (or File Name) too. (Since 1 Jan comes before 31 Dec)
Dim dMaxDate AS Date, wsForLoop AS Worksheet, sTestString AS String
dMaxDate = DateSerial(1900,1,0) 'Default to 0
For Each wsForLoop In ThisWorkbook.Worksheets 'Loop through every worksheet
sTestString = wsForLoop.Name 'Get the name of the sheet
If InStr(sTestString, " ") > 0 Then sTestString = Mid(sTestString, 1+InStr(sTestString, " ")) 'Remove the Weekday
'If you need to add the Month/Year from your filename, do that here
If IsDate(sTestString) Then 'Only check Worksheets with Dates for Names
If cDate(sTestString) > dMaxDate Then dMaxDate = cDate(sTestString) 'If this is a later date then store it
End If
Next wsForLoop 'Return to start of loop
If dMaxDate < DateSerial(1900, 1, 1) Then dMaxDate = Now-1 'If we have no Worksheets with Dates for Names then default to yesterday
With ThisWorkbook.Worksheets.Add 'Add a new sheet
'Change the Format if you are adding the Month and/or Year from Filename
.Name = Format(dMaxDate+1, "ddd d mmm") 'And Name it the day after our stored date
End With
try using below, you can use counter instead of 1.
SZTodayDate = Format(Date + 1, "ddd") & Format(Date + 1, " dd")
Disclaimer: This is a fairly specific bug I think I ran into in Excel but it's weird enough that I'll never find an answer to fix it, if it's even possible, if I don't post it here. It is an interesting one though so bear with me.
So a little context, I wrote some code that lets me capture a time stamp in column A when I input into column B. That works fine. I added a bit so it prompts the user if they are sure they want to change an entry after it has been entered, to keep the integrity of the time stamp. This also works.
During testing I ran into an issue, however. If I simply type a number into col A, the number 5 for example, it forces it into the format 1/5/1900 00:00. Makes sense to me, as Excel clearly chose 1900 as an arbitrary starting point. But if I try to edit this date, the prompt asking me if I want to change it shows up as 1/4/1900 (screenshot below). For the longest time I couldn't figure out why it was off by 1. I realized that any input between 1 and 60 (dates jan 1 to feb 29) caused this problem. Any dates after 3/1/1900 prompted me correctly. I did some digging and I found that the year 1900 doesn't have a leap year, so the number 60 should resolve to 3/1/1900 but instead goes to 2/29/1900 in Excel.
I know it's a small issue and only affects 60 possible entries in column A, but I feel helpless to fix it as it seems that the problem is how Excel calculates the leap year in 1900 when it shouldn't. Does anyone have a workaround, or at least a confirmation that this is a problem with Excel and not my code?
Screenshot of 3 cases of editing column A.
The 1st and 3rd results are expected. The middle one shows that even though the previous field was actually Jan 5, the prompt shows up as Jan 4. I'll post the code I have below in case anyone wants to try the same thing.
Private lastVal As Variant
Private Sub Worksheet_Change(ByVal Target As Range)
Dim timeCol, taskCol As Integer
Dim sRow, sCol As Integer
Dim currentCell As Range
timeCol = 1
taskCol = 2
sRow = Target.row
sCol = Target.Column
Set currentCell = Cells(sRow, sCol)
'Checks for timestamp or task column. If Cell wasn't empty, prompt user to
'confirm the change
If sCol = timeCol Or sCol = taskCol Then
If lastVal <> "" Then
response = MsgBox("Old Value: " & lastVal & Chr(10) & Chr(10) _
& "New Value: " & Cells(sRow, sCol) & Chr(10) & Chr(10) _
& "Are you sure you want to make this change?", _
vbYesNo + vbQuestion, "Change Confirmation")
If response = vbYes Then
'Do nothing
Else
'Reject the change
Application.EnableEvents = False
currentCell = lastVal
Application.EnableEvents = True
End If
End If
End If
'Checks for task column. If timestamp cell at current row is empty
'and something was entered into task column, fills timestamp cell
If sCol = taskCol Then
If Cells(sRow, timeCol) = "" = True Then
If currentCell <> "" Then
Application.EnableEvents = False
Cells(sRow, timeCol) = Now()
Application.EnableEvents = True
End If
End If
End If
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim sRow, sCol
Dim currentCell As Range
sRow = Target.row
sCol = Target.Column
Set currentCell = Cells(sRow, sCol)
lastVal = currentCell
End Sub
Here it is:
When Lotus 1-2-3 was first released, the program assumed that the year 1900 was a leap year, even though it actually was not a leap year. This made it easier for the program to handle leap years and caused no harm to almost all date calculations in Lotus 1-2-3.
When Microsoft Multiplan and Microsoft Excel were released, they also assumed that 1900 was a leap year. This assumption allowed Microsoft Multiplan and Microsoft Excel to use the same serial date system used by Lotus 1-2-3 and provide greater compatibility with Lotus 1-2-3. Treating 1900 as a leap year also made it easier for users to move worksheets from one program to the other.
Although it is technically possible to correct this behavior so that current versions of Microsoft Excel do not assume that 1900 is a leap year, the disadvantages of doing so outweigh the advantages.
https://support.microsoft.com/en-us/help/214326/excel-incorrectly-assumes-that-the-year-1900-is-a-leap-year
This is a well-known bug that was intentionally introduced by the original Excel team to maintain compatibility with Lotus 1-2-3.
I'm importing a .csv file from another program into Excel. The date format is text, formatted as follows :
mm/dd/yy or
07/03/17
The imported file is very unstructured, with more than just dates in the first field.
I want to write 2017-07-03 into the cell (2,13)
Here is the code I'm using
ActiveSheet.Cells(2, 13).Select
ActiveCell.FormulaR1C1 = "=IF(LEN(RC[-12]))=8, _ 'How I identify date
20&MID((RC[-12]),7,2)&" - "& 'To get 2017 4 digit Year
MID((RC[-12]),1,2)&" - "& 'To extract 2 digit month
MID((RC[-12]),4,2)),"""")" 'To extract 2 digit day
This gives me Runtime error 13 - Type mismatch.
I think that my code is causing the error by mixing values and text, but I cannot see where.
The reasons for your error message is due to the formula not being properly created.
It should look like:
Cells(2, 13).FormulaR1C1 = "=IF(LEN(RC[-12])=8, 20 & MID(RC[-12],7,2) & ""-"" & MID(RC[-12],1,2) & ""-"" & MID(RC[-12],4,2),"""")"
Instead of writing formulas to the worksheet, I suggest doing the conversion within VBA and then writing the results to the worksheet. This can make your code easier to understand, debug, and maintain in the future.
The code below could be shortened, but purposely is not so as to provide more clarity. It is written as a macro that will process everything in column A, and write the dates to column M, in the format you specify.
I note that in your question, you specify a format of 2017-07-03, but in your code, you generate a format of 2017 - 07 - 03. I generated the former in the code, but it should be obvious how to change to the latter if that is what you really want.
Also note that in the code I used the default conversion for Excel for 2-digit years, where two digit years are assumed to be in the range 1930 - 2029. That can be changed if necessary.
The code uses a more involved method of assuring the value being converted is truly a date. But it does not check for "illegal" dates and will convert, for example 2/31/17 to 2017-03-03. Your formula method would return the string 2017-02-31 It would be trivial, in the VBA macro, to add code to flag this kind of problem, if it might be an issue.
There are other ways to check for valid dates, including seeing if CDate or VBA's DateValue functions return a date or an error. But these may not work properly across workbooks in different locale's, with different default short date formats in the windows Regional Settings.
Instead of writing the results as text, the results could be written as a real date formatted as you wish with the .numberformat property of the cell (which could be used in future calculations), and that option is in the comments in the macro.
If you require that the result be dynamic, with a formula, the macro could be easily converted into a User Defined Function, but you would have to assure that the cell format is "text" else Excel will try to convert the resultant date into a "real date" (depending on which of the two formats you really want).
Post back with any questions about the code.
Option Explicit
Sub ConvertOnlyDates()
Dim V As Variant
Dim YR As Long, MN As Long, DY As Long
Dim DT As Date
Dim WS As Worksheet
Dim rSrc As Range, C As Range
'Define the range to check: Columns A
'Always best to explicitly define worksheets and cells
' and not rely on ActiveSheet, Activate, Select, etc
Set WS = Worksheets("sheet2")
With WS
Set rSrc = .Range(.Cells(1, 1), .Cells(.Rows.Count, 1).End(xlUp))
End With
For Each C In rSrc
'check if a date
V = Split(C.Text, "/")
If UBound(V) = 2 Then
If V(0) > 0 And V(0) <= 12 _
And V(1) > 0 And V(1) <= 31 _
And V(2) >= 0 And V(2) <= 99 Then
MN = V(0)
DY = V(1)
'note that this is Excel's default (at least for now)
YR = V(2) + IIf(V(2) < 30, 2000, 1900)
DT = DateSerial(YR, MN, DY)
'Can be written as text
' or as a real date with proper formatting
' REAL DATE
'With C.Offset(0, 12) 'write in column M
' .NumberFormat = "yyyy-mm-dd"
' .Value = DT
'End With
With C.Offset(0, 12)
.NumberFormat = "#"
.Value = Format(DT, "yyyy-mm-dd")
End With
End If
End If
Next C
End Sub
You haven't appropriately closed your strings with double quotes for each line. Using the continuation character _ doesn't allow you to break a string in the middle. You can do this if you properly concatenate:
ActiveCell.FormulaR1C1 = "=IF(LEN(RC[-12]))=8," & _ 'How I identify date
"20&MID((RC[-12]),7,2)&" - " & _ 'To get 2017 4 digit Year
"MID((RC[-12]),1,2)&" - " & _ 'To extract 2 digit month
"MID((RC[-12]),4,2)),"""")" 'To extract 2 digit day
(Your code will be far more readable if you take the time to indent continued lines in the fashion shown above. You can more quickly and easily pick out the destination variable and the assignment if you follow this format.)
I am trying to reference a file that has the date of the previous Friday at the end in the form of mm.dd.yy.
I need to now take that date and add it to the end of a string, to end of a string in order to open select the other workbook. This is what I have right now.
File Name:
Submittals Wk Ending 06.02.17.xlsx
This is what I have so far
Dim wrbk As String
Dim weekdate As String
range("a1").value="=TODAY()-WEEKDAY(TODAY())-1"
weekdate = Range("a1").Value
'range("b1").value="06.02.17"
'weekdate = Range("b1").Value
msgbox weekdate 'use to check what the date format is
wrbk = "Submittals Wk Ending " & weekdate
Windows(wrbk & ".xlsx").Activate
When I read it from B2 with the typed in format of 06.02.17 it works, however no matter what I do, I cannot get it to read it from A1 because it changes the format to m/d/yyyy. I have tried to copy it and paste as value. Nothing seems to work.
I have the other workbook open as well when I try to run it.
Any ideas? Thanks!
To get the previous Friday of any date, try below UDF. This should work fine if the Date NumberFormat is same as your System's Date format. The key is the CDate() which converts according to System's Date format which Office apps defaults to.
Option Explicit
Function GetLastFridayDate(AnyDate As Variant) As Date
Dim dInput As Date, dLastFriday As Date
dInput = CDate(AnyDate)
dLastFriday = dInput - Weekday(dInput) + vbFriday - IIf(Weekday(dInput) > vbFriday, 0, 7)
GetLastFridayDate = dLastFriday
End Function
Try
Range("A1").Value = Format$(Date - Weekday(Date) - 1, "MM.DD.YY")
I am trying to create a VBA macro which will search the rows on the basis of the following criteria:
First it will look for a name specified in the macro in the name column.
If the name is found it will proceed to check the 'submitted' column and check whether the submitted date is between a weekly date. (like if the date is between 2/23/2015-2/27/2015).
If the date lies between the specified dates then the macro will group the activities based on their names and add the number of hours based on the values in the hours tab.
This whole data is finally to be copied and pasted into another worksheet in the same workbook.
So far I have only been able to get to searching for the names part and being a newbie to VBA macro I have absolutely no idea of how to proceed.
So far I have done pathetically since yesterday to come up with a solution. Please help. I am attaching my code, though I wonder if its of any use
Sub Demo()
Dim rngCell As Range
Dim lngLstRow As Long
Dim strFruit() As String
Dim intFruitMax As Integer
intFruitMax = 3
ReDim strFruit(1 To intFruitMax)
strFruit(1) = "A"
strFruit(2) = "B"
strFruit(3) = "C"
lngLstRow = ActiveSheet.UsedRange.Rows.Count
For Each rngCell In Range("J2:J" & lngLstRow)
For i = 1 To intFruitMax
If strFruit(i) = rngCell.Value Then
rngCell.EntireRow.Copy
Sheets("Inventory").Select
Range("A65536").End(xlUp).Offset(1, 0).Select
Selection.PasteSpecial xlPasteValues
Sheets("Sheet1").Select
End If
Next i
Next
End Sub
I believe the points below will allow you to progress although it cannot be a full answer because you do not give enough information for that. Warning: I do not explain my macros fully. Look up Help for the statements I use and try to work out why they have the effect they do. Come back with questions as necessary but the more you can work out for yourself, the more you will develop your VBA knowledge.
lngLstRow = ActiveSheet.UsedRange.Rows.Count
It is best to avoid ActiveSheet and UsedRange unless you know exactly what you are doing.
If you use the active worksheet, you are relying on the user having the correct worksheet active when they start the macro. You may one day want to allow the user to select which worksheet is the target for a macro but I doubt that is the case here. If possible be explicit. For example:
With Worksheets("New Data")
.Range("A1").Values = "Date"
End With
Above I explicit specify the worksheet I wish to use. It does not matter what worksheet is active when the user starts the macro. If I come back to the macro after six months, I do not have to remember which of the 20 worksheets it operates on.
Excel’s definition of UsedRange does not always mean what the programmer thinks its means. Do not use it until you have tried it out on a variety of test worksheets. In particular, try (1) formatting cells outside the range with values and (2) leaving the left columns and top rows unused. Try Debug.Print .UsedRange.Address. You will be surprised at some of the ranges you get.
Create a new workbook. Place values in E4, C7 and B10. Merge cells F12 and F13 and place a value in the merged area. It does not matter what those values are.
Copy this macro to a module and run it:
Option Explicit
Sub Test1()
Dim ColFinal As Long
Dim RowFinal As Long
Dim RowFinalC As Long
With Sheets("Sheet1")
RowFinal = .Cells.Find(What:="*", After:=.Range("A1"), LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious).Row
ColFinal = .Cells.Find(What:="*", After:=.Range("A1"), LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious).Column
RowFinalC = .Cells(Rows.Count, "C").End(xlUp).Row
End With
Debug.Print "ColFinal" = ColFinal
Debug.Print "RowFinal" = RowFinal
Debug.Print "RowFinalC" = RowFinalC
End Sub
The output will be:
ColFinal=5
RowFinal=12
RowFinalC=7
In most cases, Find is the best way of locating the last row and/or column of a worksheet. What:="*"means look for anything. Notice that I have different values for SearchOrder. It does not matter that the worksheet is not rectangular; the last row and the last column do not have to be the same cell.
However, there is no method of finding the last row or column that works in every situation. Find has not “seen” the merged cell when searching by column. (Warning, I am using an old version of Excel and this may have been fixed in your version.)
You want the last used cell in column J. My technique for finding the last row in column C may be the easiest technique for you.
Consider:
intFruitMax = 3
ReDim strFruit(1 To intFruitMax)
strFruit(1) = "A"
strFruit(2) = "B"
strFruit(3) = "C"
For i = 1 To intFruitMax
Next i
There is nothing wrong with your code but this macro shows a different approach that may be more convenient:
Sub Test2()
Dim Fruit() As Variant
Dim InxFruit As Long
Fruit = Array("A", "B", "C")
For InxFruit = LBound(Fruit) To UBound(Fruit)
Debug.Print Fruit(InxFruit)
Next
End Sub
It is becoming uncommon to have a three letter prefix specifying the type of a variable. As someone asked: “Is strFruit really more useful than Fruit?”. Avoid variable names like i. It probably does not matter with such a small macro but I have tried to decipher macros with a bunch of meaningless names and can assure you it is a nightmare. InxFruit says this is an index into array Fruit. I can look at macros I wrote years ago and immediately know what all the variables are.
LBound(Fruit) will always be zero if you use Array. Note also that Fruit has to be of type Variant. The advantage is that when you want to add fruits D and E, you just change to:
Fruit = Array("A", "B", "C", "D", "E")
If the name is found it will proceed to check the 'submitted' column and check whether the submitted date is between a weekly date. (like if the date is between 2/23/2015-2/27/2015).
Your technique for finding rows for interesting fruit is not the best technique but I think it is good enough. I am giving you enough to think about without discussing other approaches.
I am guessing you want to know if the date is between Monday and Friday of the current week.
Now() gives you the current date and time. The next macro shows how to calculate the Monday and Friday for any day of a week. If you chose to copy this technique, please document it properly for the benefit of the poor sod who has to update your macro in a year’s time. This macro is all clever arithmetic with functions and constants. I do not like clever code, unless it is properly documented, because it is usually the programmer showing off rather than solving the problem using the simplest method.
Sub Test3()
Dim Friday As Date
Dim InxDate As Long
Dim Monday As Date
Dim TestDates() As Variant
Dim Today As Date
Dim TodayDoW As Long
TestDates = Array(DateSerial(2015, 2, 22), DateSerial(2015, 2, 23), _
DateSerial(2015, 2, 24), DateSerial(2015, 2, 25), _
DateSerial(2015, 2, 26), DateSerial(2015, 2, 27), _
DateSerial(2015, 2, 28), Now())
For InxDate = 0 To UBound(TestDates)
Today = TestDates(InxDate)
TodayDoW = Weekday(Today)
Monday = DateSerial(Year(Today), Month(Today), Day(Today) + vbMonday - TodayDoW)
Friday = DateSerial(Year(Today), Month(Today), Day(Today) + vbFriday - TodayDoW)
Debug.Print "Today=" & Format(Today, "ddd d mmm yy") & _
" Monday=" & Format(Monday, "ddd d mmm yy") & _
" Friday=" & Format(Friday, "ddd d mmm yy")
Next
End Sub
Note that Excel holds dates as numbers so you can write If Monday <= TransDate And TransDate <= Friday Then.
Your technique for moving data from one worksheet to another is clumsy. This macro moves every row with “A”, “a”, “B”, “b”, “C” or “c” in column J from worksheet “Sheet2” to “Sheet3”. I believe you will agree the innermost loop in clearer than yours.
Sub Test4()
' I assume row 1 contains column headers and is not to be copied
' to the new worksheet. Constants are a good way of making such
' assumptions explicit and easy to change if for example to add
' a second header row
Const RowSht2DataFirst As Long = 2 ' This only applies to Sheet2
Const ColFruit As Long = 10 ' This applies to both sheets
Dim Fruit() As Variant
Dim FruitCrnt As String
Dim InxFruit As Long
Dim RowSht2Crnt As Long
Dim RowSht2Last As Long
Dim RowSht3Next As Long
Dim Wsht2 As Worksheet
Dim Wsht3 As Worksheet
' It takes VBA some time to evaluate Worksheets("Sheet2") and
' Worksheets("Sheet3"). This means it only has to do it once.
Set Wsht2 = Worksheets("Sheet2")
Set Wsht3 = Worksheets("Sheet3")
' BTW Please don't use the default names for a real workbook.
' It is so much easier to understand code with meaingful names
Fruit = Array("A", "B", "C")
With Wsht3
' Place new rows under any existing ones.
RowSht3Next = .Cells(Rows.Count, ColFruit).End(xlUp).Row + 1
End With
With Wsht2
RowSht2Last = .Cells(Rows.Count, ColFruit).End(xlUp).Row
For RowSht2Crnt = RowSht2DataFirst To RowSht2Last
FruitCrnt = UCase(.Cells(RowSht2Crnt, ColFruit).Value)
For InxFruit = LBound(Fruit) To UBound(Fruit)
If Fruit(InxFruit) = FruitCrnt Then
.Rows(RowSht2Crnt).Copy Destination:=Wsht3.Cells(RowSht3Next, 1)
RowSht3Next = RowSht3Next + 1
Exit For
End If ' Match on fruit
Next InxFruit
Next RowSht2Crnt
End With ' Wsht3
End Sub