Lookup dates and calculate expiratrion - vba

I have two data reports where I sort the data in data report 1 and move it to a sheet called "List". To finish off the report I then,
Get a date from data report two for every line I have in the sorted list. To do this I have tried to take the action title in column "G" in the sheet "List" and then I search for it in the sheet "Data2" in column "C", then I return the row number and want to save a number there is in the column "G". This number is the days to deadline and can either be a positive or negative number.
Take today's date + / - the number and put the modified date and the sheet "Lists" in column "N" to be able to see when every task has deadline.
I can't get other kinds of data in the reports so I have to solve this with some VBA. The code I have tried is this.
Sub InsertDate()
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim i As Integer
Dim RowNr As Long
Dim ActionTitle As String
Dim DaysToExp As Long
Dim ExpDate As Date
Dim Found As Range
Dim FoundRow As Long
Dim Sign As String
Dim Days As String
Dim RowNr2 As Long
ScreenUpdate = False
RowNr = ThisWorkbook.Worksheets("List").Range("A" & Rows.count).End(xlUp).row
RowNr2 = ThisWorkbook.Worksheets("Data2").Range("A" & Rows.count).End(xlUp).row
Set ws1 = ThisWorkbook.Worksheets("List")
Set ws2 = ThisWorkbook.Worksheets("Data2")
ws1.Range("N1").Value = "Expected start date"
For i = 2 To RowNr
ActionTitle = ws1.Range("G" & i).Value
Set Found = ws2.Range("C1:C" & RowNr2).Find(What:=ActionTitle, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows).Activate
FoundRow = ActiveCell.row
Days = ws2.Range("G" & FoundRow).Value
If Days = "" Then
DaysToExp = DaysToExp + 0
ElseIf Left(Days, 1) = "-" Then
Sign = "-"
DaysToExp = Replace(Days, "-", "")
Else
Sign = "+"
DaysToExp = DaysToExp + Days
End If
ExpDate = "=TODAY() & Sign & DaysToExp"
ThisWorkbook.Worksheets("List").Range("N" & i).Value = ExpDate
Next i
ScreenUpdate = True
End Sub

I've tightened up your code a bit and removed the .Find in place of a worksheet function .Match. You don't need to parse out the sign of Days since you can add a negative number to the date.
Sub InsertDate()
Dim ws1 As Worksheet, ws2 As Worksheet
Dim i As Long
Dim RowNr As Long, DaysToExp As Long, FoundRow As Long, RowNr2 As Long
Dim ActionTitle As String, Sign As String, Days As String
Dim ExpDate As Date
Dim Found As Range
Application.ScreenUpdating = False
Set ws1 = ThisWorkbook.Worksheets("List")
Set ws2 = ThisWorkbook.Worksheets("Data2")
RowNr2 = ws2.Range("A" & Rows.Count).End(xlUp).Row
With ws1
RowNr = .Range("A" & Rows.Count).End(xlUp).Row
.Range("N1").Value = "Expected start date"
For i = 2 To RowNr
ActionTitle = ws1.Range("G" & i).Value
If CBool(Application.CountIf(ws2.Range("C1:C" & RowNr2), ActionTitle)) Then
FoundRow = Application.Match(ActionTitle, ws2.Range("C1:C" & RowNr2), 0)
Days = ws2.Range("G" & FoundRow).Value
ExpDate = Date + Days
.Range("N" & i).Value = ExpDate
Else
Debug.Print "missing " & ActionTitle
End If
Next i
End With
Application.ScreenUpdating = True
End Sub
I threw a debug.print in that will report to the VBE's Immediate window if ActionTitle cannot be found.

Related

Looping over Visible Range Issue

The function is supposed to loop over a filtered range appending a certain date to the first "i" lines then moving to the next date and repeating.
It is appending everything to the header instead of moving down a row each time.
It is not erroring, just not acting as expected. Where am I going wrong on this?
Sub Function()
Dim wsExport As Worksheet
Set wsExport = Workbooks("Export Workbook").Worksheets("Export")
Dim uiStartDate As Variant 'I'm using the prefix ui to be User Input
Dim uiEndDate As Variant
Dim uiCount As Variant
Dim cStartDate As Long 'Converted to date
Dim cEndDate As Long
Dim cCount As Long
Dim iDate As Long 'Counter for the date
Dim i As Long 'Counter for the number of items per day.
Dim j As Long 'Counter for Rows
Dim lRow As Long
lRow = Cells.Find(What:="*", LookAt:=xlPart, _
LookIn:=xlFormulas, SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, MatchCase:=False).Row
'Prompt the user for the start date and end date
'uiStartDate = InputBox("Input the first day of week in the format of 01/20/2018", "Start Date User Input")
'uiEndDate = InputBox("Input the last day of week in the format of 01/25/2018", "End Date User Input")
'uiCount = InputBox("Input the number of items per day.", "Installtion Quantity User Input")
uiStartDate = "1/20/2018" 'This is to speed during testing. Will use the above for actual code
uiEndDate = "1/25/2018"
uiCount = "2"
'Convert to their proper data types. (User inputs have to be variants to begin with)
cStartDate = CDate(uiStartDate)
cEndDate = CDate(uiEndDate)
cCount = CLng(uiCount)
With wsExport.Range("A:AP")
.AutoFilter Field:=19, Criteria1:=">=" & uiStartDate
End With
iDate = cStartDate
j = 2
i = 1
Do While j <= lRow
DoEvents
If Not wsExport.Rows(j).Hidden Then
wsExport.Range("S" & j).Value = wsExport.Range("S" & j).Value & "-" & iDate
i = i + 1
End If
If i > cCount Then
i = 1
iDate = iDate + 1
End If
If iDate > cEndDate Then
j = lRow + 1
End If
j = j + 1
Loop
End Sub
Here's a simplified example using a different approach to looping over the table:
EDIT: updated to your actual process of incrementing the date every two rows...
Sub Tester()
Dim sht As Worksheet, rngTable As Range, rw As Range, r As Long
Dim sDate, eDate, dt, i As Long
Set sht = ActiveSheet
Set rngTable = sht.Range("A1").CurrentRegion
rngTable.AutoFilter 'clear any previous filter
rngTable.AutoFilter field:=4, Criteria1:=">3" 'filter to required rows only
'some dates...
sDate = Date
eDate = Date + 3
dt = sDate 'set date to add
i = 0
For r = 2 To rngTable.Rows.Count
Set rw = rngTable.Rows(r)
'is the row visible?
If Not rw.Hidden Then
With rw.Cells(2)
.Value = .Value & " - " & Format(dt, "dd/mm/yyyy")
End With
i = i + 1
If i Mod 2 = 0 Then dt = dt + 1 '<< next date every 2 visible rows
If dt > eDate Then Exit For '<< exit if run out of dates
End If
Next r
End Sub
xlCellTypeVisible does not do what you want when working with an offset from a cell like this. Just use an IF instead:
For i = 1 To cCount
currentRow = currentCell.Offset(1, 0).Row
Set currentCell = wsExport.Range("S" & currentRow)
if currentcell.rowheight > 0 then currentCell.Value = currentCell.Value & "- " & iDate
Next i

Random row selection in multiple excel sheets

I have an output excel file from another macro which has multiple sheets (named 100,101,102... etc.) Sheet numbers will vary depending on prior macro's output.
Also there is a sheet named sheet1 which has info about how many random rows should be selected from 100,101,102... etc.
I tried to merge/combine what i could find from similar macros but i guess the loop part is way over my head.
I will run the macro from another "main" excel. which will open related output xls.
Then it will lookup for random rows amount from sheet1 and then select that number of random rows in related sheet and move to next sheet. (I'm getting the correct amount from lookup (used index match))
But for randomized part i was not able to make it work for multiple sheets.
It does not matter if it selects and colors the rows or copies and pastes them to another sheet/wb. Both is ok, but I need to automate this process since i have so much data waiting.
The macro i have managed so far is below, since I'm a newbie there may be unrelated or unnecessary things.
Is it possible?
Sub RANDOM()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Dim Sh As Worksheet
Dim Durat As Long
StartTime = Now()
Dim mvn As Workbook
Dim FPath As String
Dim newWB As Workbook
Dim SheetN As Integer
Dim I As Long
FPath = ThisWorkbook.Path
Set mvn = Workbooks.Open(FileName:=ActiveWorkbook.Path & "\" &
Sheets("Data").Range("C2").Value & " " & Sheets("Data").Range("C3").Value
& " Muavinbol" & ".xls")
SheetN = mvn.Worksheets.Count
Set SampleS = mvn.Sheets("Sheet1")
For Each Sh In mvn.Worksheets
Sh.Activate
If Sh.Name <> "Sheet1" Then
Dim lookupvalue As Integer
Dim ranrows As Integer
Dim randrows As Integer
lookupvalue = Cells(1, 1).Value
ranrows = Application.WorksheetFunction.Index(mvn.Sheets("Sheet1")_
.Range("S1:S304"), Application.WorksheetFunction.Match(lookupvalue,
mvn.Sheets("Sheet1").Range("$D$1:$D$304"), 0))
'MsgBox lookupvalue & " " & ranrows
End If
Next Sh
Durat = Round((Now() - StartTime) * 24 * 60 * 60, 0)
'MsgBox Durat & " seconds."
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
Here is an example (i have integrated some code, adapted from other places, and added the references in to the code itself) I would welcome feedback from other users and can refine.
Sheet1 has the number of rows to return and the sheet names (i have used a short list)
The other sheets have some random data e.g. Sheet2
The code reads the sheet names into one array and the number of rows to randomly choose from each sheet into another array.
It then loops the sheets, generates the number of required random rows by selecting between the first and the start row in the sheet (this currently doesn't have error handling in case specified number of random rows exceeds available number ,but then could set numRows to lastRow. Union is used to collect these for the given sheet and they are copied to the next available row in the target sheet of another workbook. Union can't be used across worksheets sadly so a workaround has to be found, i chose this copy for each worksheet.
I have made some assumptions about where to copy from and to but have a play. I have also left some of your code in and currently set mnv = ThisWorkbook and the workbook to copy to is called otherWorkbook. Yours may be differently named and targeted but this was aimed at showing you a process for generating numbers and copying them in a loop.
Have used a function by Rory to test if the worksheet exists.
Example result:
Option Explicit
Public Sub RANDOM()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Dim Sh As Worksheet
Dim Durat As Long
Dim mvn As Workbook
Dim FPath As String
Dim newWB As Workbook
'Dim SheetN As Long
Dim i As Long
Dim otherWorkbook As Workbook
Dim targetSheet As Worksheet
Dim startTime As Date
Dim mnv As Workbook
Dim SampleS As Worksheet
startTime = Now()
FPath = ThisWorkbook.Path
'Set mvn = Workbooks.Open(Filename:=ActiveWorkbook.Path & "\" & Sheets("Data").Range("C2").Value & " " & Sheets("Data").Range("C3").Value & " Muavinbol" & ".xls")
Set mnv = ThisWorkbook
Set otherWorkbook = Workbooks.Open("C:\Users\HarrisQ\Desktop\My Test Folder\Test.xlsx")
Set targetSheet = otherWorkbook.Sheets("TargetSheet")
Set SampleS = mnv.Worksheets("Sheet1")
Dim worksheetNames()
Dim numRandRows()
worksheetNames = SampleS.Range("$D$1:$D$3").Value
numRandRows = SampleS.Range("$S$1:$S$3").Value
Dim copyRange As Range
Dim currSheetIndex As Long
Dim currSheet As Worksheet
Dim selectedRows As Range
For currSheetIndex = LBound(worksheetNames, 1) To UBound(worksheetNames, 1)
If WorksheetExists(CStr(worksheetNames(currSheetIndex, 1))) Then
Set currSheet = mnv.Worksheets(worksheetNames(currSheetIndex, 1))
With currSheet
Dim firstRow As Long
Dim lastRow As Long
Dim numRows As Long
firstRow = GetFirstLastRow(currSheet, 1)(0) 'I am using Column A (1) to specify column to use to find first and last row.
lastRow = GetFirstLastRow(currSheet, 1)(1)
numRows = numRandRows(currSheetIndex, 1)
Set selectedRows = RandRows(currSheet, firstRow, lastRow, numRows) 'Union cannot span different worksheets so copy paste at this point
Dim nextTargetRow As Long
If IsEmpty(targetSheet.Range("A1")) Then
nextTargetRow = 1
Else
nextTargetRow = targetSheet.Cells(targetSheet.Rows.Count, "A").End(xlUp).Row + 1
End If
selectedRows.Copy targetSheet.Cells(nextTargetRow, 1)
Set selectedRows = Nothing
End With
End If
Next currSheetIndex
Durat = Round((Now() - startTime) * 24 * 60 * 60, 0)
'MsgBox Durat & " seconds."
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
Private Function RandRows(ByRef currSheet As Worksheet, ByVal firstRow As Long, ByVal lastRow As Long, ByVal numRows As Long) As Range
'http://www.ozgrid.com/VBA/RandomNumbers.htm
Dim iArr As Variant
Dim selectedRows As Range
Dim i As Long
Dim r As Long
Dim temp As Long
Application.Volatile
ReDim iArr(firstRow To lastRow)
For i = firstRow To lastRow
iArr(i) = i
Next i
For i = lastRow To firstRow + 1 Step -1
r = Int(Rnd() * (i - firstRow + 1)) + firstRow
temp = iArr(r)
iArr(r) = iArr(i)
iArr(i) = temp
Next i
Dim currRow As Range
For i = firstRow To firstRow + numRows - 1
Set currRow = currSheet.Cells.Rows(iArr(i))
If Not selectedRows Is Nothing Then
Set selectedRows = Application.Union(selectedRows, currRow)
Else
Set selectedRows = currRow
End If
Next i
If Not selectedRows Is Nothing Then
Set RandRows = selectedRows
Else
MsgBox "No rows were selected for copying"
End If
End Function
Private Function GetFirstLastRow(ByRef currSheet As Worksheet, ByVal colNum As Long) As Variant
'colNum determine which column you will use to find last row
Dim startRow As Long
Dim endRow As Long
endRow = currSheet.Cells(currSheet.Rows.Count, colNum).End(xlUp).Row
startRow = FirstUsedCell(currSheet, colNum)
GetFirstLastRow = Array(startRow, endRow)
End Function
Private Function FirstUsedCell(ByRef currSheet As Worksheet, ByVal colNum As Long) As Long
'Finds the first non-blank cell in a worksheet.
'https://www.excelcampus.com/library/find-the-first-used-cell-vba-macro/
Dim rFound As Range
On Error Resume Next
Set rFound = currSheet.Cells.Find(What:="*", _
After:=currSheet.Cells(currSheet.Rows.Count, colNum), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
On Error GoTo 0
If rFound Is Nothing Then
MsgBox currSheet & ":All cells are blank."
End
Else
FirstUsedCell = rFound.Row
End If
End Function
Function WorksheetExists(sName As String) As Boolean
'#Rory https://stackoverflow.com/questions/6688131/test-or-check-if-sheet-exists
WorksheetExists = Evaluate("ISREF('" & sName & "'!A1)")
End Function
Since QHarr's code needed to have all worksheet names should exist in the workbook did not work for me in the end. But with merging it some other project's function i made it work.
Opens an output xlsx file in same folder,
Index&Match to find the random rows amount
loop through all sheets with random function
then paste all randomized rows into Sheet named RASSAL
It may be unefficient since I really dont have much info on codes, but guess i managed to modify it into my needs.
Open to suggestions anyway and thanks to #QHarr very much for His/Her replies.
Sub RASSALFNL()
'Application.ScreenUpdating = False
'Application.DisplayAlerts = False
Dim Durat As Long
startTime = Now()
Dim Sht As Worksheet
Dim mvn As Workbook
Dim FPath As String
Dim newWB As Workbook
Dim SheetN As Long
Dim i As Long
Dim lookupvalue As Long
Dim indexrange As Range
Dim matchrange As Range
Dim ranrows As Long
Dim firstRow As Long
Dim lastRow As Long
Dim numRows As Long
Dim sayf As String
Dim nextTargetRow As Long
Dim Rassal As Worksheet
Dim rngToCopy As Range
Dim sampleCount As Long
Dim ar() As Long
Dim total As Long
Dim rowhc As Long
FPath = ThisWorkbook.Path
Set mvn = Workbooks.Open(FileName:=ActiveWorkbook.Path & "\" &
Sheets("Data").Range("C2").Value & " " & Sheets("Data").Range("C3").Value
& " Muavinbol" & ".xlsx")
SheetN = mvn.Worksheets.count
Set SampleS = mvn.Sheets("Sheet1")
Set Rassal = Worksheets.Add
Rassal.Name = "RASSAL"
Set indexrange = SampleS.Range("$S$8:$S$304")
Set matchrange = SampleS.Range("$D$8:$D$304")
mvn.Activate
For Each Sht In mvn.Worksheets
Sht.Activate
If Sht.Name = "Sheet1" Or Sht.Name = "Sayfa1" Or Sht.Name = "RASSAL"
Then
'do nothing
Else
lookupvalue = Sht.Cells(1, 1).Value
ranrows = Application.WorksheetFunction.Index(indexrange,
Application.WorksheetFunction.Match(lookupvalue, matchrange, 0))
With Sht
firstRow = GetFirstLastRow(Sht, 1)(0)
lastRow = GetFirstLastRow(Sht, 1)(1)
numRows = ranrows
sayf = Sht.Name
'MsgBox sayf & " " & firstRow & " " & lastRow & " " &
ranrows
If numRows = 0 Then
'do nothing
Else
ar = UniqueRandom(numRows, firstRow, lastRow)
Set rngToCopy = .Rows(ar(0))
For i = 1 To UBound(ar)
Set rngToCopy = Union(rngToCopy, .Rows(ar(i)))
Next
If IsEmpty(mvn.Sheets("RASSAL").Range("A1")) Then
nextTargetRow = 1
Else
nextTargetRow =
mvn.Sheets("RASSAL").Cells(mvn.Sheets("RASSAL").Rows.count,
"A").End(xlUp).Row + 1
End If
rngToCopy.Copy Rassal.Cells(nextTargetRow, 1)
Set rngToCopy = Nothing
End If
End With
End If
Next Sht
rowhc = Rassal.Cells(Rows.count, 1).End(xlUp).Row
Durat = Round((Now() - startTime) * 24 * 60 * 60, 0)
MsgBox rowhc & " " & "random selections made in" & " " & Durat & "
seconds."
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
Private Function GetFirstLastRow(ByRef Sht As Worksheet, ByVal colNum As
Long) As Variant
'colNum determine which column you will use to find last row
Dim firstRow As Long
Dim lastRow As Long
lastRow = Sht.Cells(Sht.Rows.count, colNum).End(xlUp).Row
firstRow = FirstUsedCell(Sht, colNum)
GetFirstLastRow = Array(firstRow, lastRow)
End Function
Private Function FirstUsedCell(ByRef Sht As Worksheet, ByVal colNum As
Long) As Long
Dim rFound As Range
On Error Resume Next
Set rFound = Sht.Cells.Find(What:="*", _
After:=Sht.Cells(Sht.Rows.count,
colNum), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
On Error GoTo 0
If rFound Is Nothing Then
'do Nothing MsgBox Sh & ":All cells are blank."
End
Else
FirstUsedCell = rFound.Row
End If
End Function
Function UniqueRandom(ByVal numRows As Long, ByVal a As Long, ByVal b As
Long) As Long()
Dim i As Long, j As Long, x As Long
ReDim arr(b - a) As Long
Randomize
For i = 0 To b - a: arr(i) = a + i: Next
If b - a < count Then UniqueRandom = arr: Exit Function
For i = 0 To b - a 'Now we shuffle the array
j = Int(Rnd * (b - a))
x = arr(i): arr(i) = arr(j): arr(j) = x ' swap
Next
' After shuffling the array, we can simply take the first portion
If numRows = 0 Then
ReDim Preserve arr(0)
Else
ReDim Preserve arr(0 To numRows - 1)
On Error Resume Next
End If
'sorting, probably not necessary
For i = 0 To count - 1
For j = i To count - 1
If arr(j) < arr(i) Then x = arr(i): arr(i) = arr(j): arr(j) = x '
swap
Next
Next
UniqueRandom = arr
End Function

Need to use code to get the last column in my data rather than use the column letter

My code currently uses the last column (in this case column o) searches all the rows in that column and clears the whole row which have a certain value in column o of that row. Please can I get some help to modify my code to automatically choose the last column rather than use the letter "o" or the value "15" of that column as for other spreadsheets it may not always use column o. See my working code below:
Sub edit_wb_1()
Dim wb As Workbook
Dim ws As Worksheet
Dim lastRow As Long, i As Long
Dim value As String
Dim OldDate, NewDate As String
OldDate = Format(DateSerial(Year(Date), Month(Date) - 1, 0), "ddmmyy")
NewDate = Format(DateSerial(Year(Date), Month(Date), 0), "ddmmyy")
Set wb = Workbooks.Open("C:\Users\ashah\Downloads\HistoricSummary.xls", 0)
Set ws = wb.Sheets("Historic Summary Page 1")
lastRow = ws.Range("o" & ws.Rows.Count).End(xlUp).Row
For i = lastRow To 2 Step -1
value = ws.Cells(i, 15).value ' Column O value.
' Check if it contains one of the keywords.
If (value Like "-") Then
ws.Rows(i).ClearContents
End If
Next
wb.SaveAs Filename:="C:\Users\ashah\Documents\TPS Shapes\TMB " & NewDate, FileFormat:=xlOpenXMLWorkbook
wb.Close
End Sub
Sub edit_wb_1()
Dim wb As Workbook
Dim ws As Worksheet
Dim lastRow As Long, i As Long
Dim lastColumn as Long
Dim value As String
Dim OldDate, NewDate As String
OldDate = Format(DateSerial(Year(Date), Month(Date) - 1, 0), "ddmmyy")
NewDate = Format(DateSerial(Year(Date), Month(Date), 0), "ddmmyy")
Set wb = Workbooks.Open("C:\Users\ashah\Downloads\HistoricSummary.xls", 0)
Set ws = wb.Sheets("Historic Summary Page 1")
lastRow = ws.Range("o" & ws.Rows.Count).End(xlUp).Row
lastColumn = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column ' gets last column in the first row (where you usually have headers so should be populated...
For i = lastRow To 2 Step -1
value = ws.Cells(i, lastColumn).value ' last col instead of Column O value.
' Check if it contains one of the keywords.
If (value Like "-") Then
ws.Rows(i).ClearContents
End If
Next
wb.SaveAs Filename:="C:\Users\ashah\Documents\TPS Shapes\TMB " & NewDate, FileFormat:=xlOpenXMLWorkbook
wb.Close
End Sub
The below alterations to your code should work.
I have made an assumption the row 1 is a header row.
I have also changed the variable name value to StrValue as value is used by built in Excel VBA functions and could cause ambiguity.
Sub edit_wb_1()
Dim wb As Workbook
Dim ws As Worksheet
Dim lastRow As Long
Dim i As Long
Dim Strvalue As String
Dim OldDate As String
Dim NewDate As String
OldDate = Format(DateSerial(Year(Date), Month(Date) - 1, 0), "ddmmyy")
NewDate = Format(DateSerial(Year(Date), Month(Date), 0), "ddmmyy")
Set wb = Workbooks.Open("C:\Users\ashah\Downloads\HistoricSummary.xls", 0)
Set ws = wb.Sheets("Historic Summary Page 1")
'This assumes row one is a header row
i = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column
lastRow = ws.Cells(ws.Rows.Count, i).End(xlUp).Row
For i = lastRow To 2 Step -1
Strvalue = ws.Cells(i, 15).value ' Column O value.
' Check if it contains one of the keywords.
If (Strvalue Like "-") Then
ws.Rows(i).ClearContents
End If
Next
Set ws = Nothing
wb.SaveAs Filename:="C:\Users\ashah\Documents\TPS Shapes\TMB " & NewDate, FileFormat:=xlOpenXMLWorkbook
wb.Close 0
Set wb = Nothing
End Sub

Extracting and copying data in an excel file

I'm extracting data froman excel file that is inside the parameter of the dates provided. But this code is not working. Anybody can help me figure this out?
Set src = wb.Sheets("Request Log Extract")
Set dest = ThisWorkbook.Sheets("Resolution Time Performance")
srcRow = src.Cells(src.Rows.Count, "K").End(xlUp).Row
destRow = dest.Cells(dest.Rows.Count, "E").End(xlUp).Row + 1
wb.Activate
For i = 2 To srcRow
If src.Cells("K" & i) >= txtStartDate.Value Or src.Cells("K" & i) <= .txtEndDate.Value Then
src.Cells("K" & i).Copy
dest.Activate
dest.Cells("E" & i).Paste
src.Activate
End If
Next
This returns an error saying :
Invalid procedure call or argument.
NOTE
txtStartDate and txtEndDate are date Types.
If I use OR in the If condition, all data were copied, but if I used And, no data is copied. I don't know whats going on.
VALUES
txtStartDate 05/13/2016
txtEndDate 05/18/2016
k2 05/14/2016
Im not sure with your txtStartDate and txtEndDate variables, but look at my code
I declared your variables, but please specify date types, also i removed dot from txtEndDate and changed cell references and now it works.
Sub extractData()
Dim src
Dim dest
Dim wb As Workbook
Set wb = ThisWorkbook
Dim txtStartDate
Dim txtEndDate
Set src = wb.Sheets("Request Log Extract")
Set dest = ThisWorkbook.Sheets("Resolution Time Performance")
srcRow = src.Cells(src.Rows.Count, "K").End(xlUp).Row
destRow = dest.Cells(dest.Rows.Count, "E").End(xlUp).Row + 1
txtStartDate = 0
txtEndDate = 100
For i = 2 To srcRow
If src.Cells(i, "K").Value > txtStartDate Or src.Cells(i, "K").Value < txtEndDate Then
src.Cells(i, "K").Copy
dest.Activate
dest.Cells(i, "E").PasteSpecial
src.Activate
End If
Next
End Sub
I think it's a date value issue
Moreover I'm guessing your code is within some userform pane and activated at some button click after which it has to compare two textboxes values to some cells content and copy/paste values accordingly
should my guessing be right (finger crossed...) try this:
Option Explicit
Private Sub CommandButton1_Click()
Dim src As Worksheet, dest As Worksheet
Dim srcRow As Long, destRow As Long, i As Long
Dim startDate As Date, endDate As Date, cellDate As Date
With Me
If Not ValidateDate("txtStartDate", .txtStartDate.Value, startDate) Then Exit Sub
If Not ValidateDate("txtEndDate", .txtEndDate.Value, endDate) Then Exit Sub
Set src = ActiveWorkbook.Sheets("Request Log Extract") '<~~ change workbook reference as per your need
Set dest = ThisWorkbook.Sheets("Resolution Time Performance")
srcRow = src.Cells(src.Rows.Count, "K").End(xlUp).Row
destRow = dest.Cells(dest.Rows.Count, "E").End(xlUp).Row + 1
For i = 2 To srcRow
If ValidateDate("src.Range(""K" & i & """)", src.Range("K" & i), cellDate) Then
If cellDate >= startDate And cellDate <= endDate Then src.Range("K" & i).Copy dest.Range("E" & i)
End If
Next
End With
End Sub
Function ValidateDate(textName As String, textValue As String, retDate As Date) As Boolean
ValidateDate = IsDate(textValue)
If ValidateDate Then
retDate = DateValue(textValue)
Else
MsgBox textValue & " is not a valid date" & vbCrLf & "please input a new value for " & textName
End If
End Function
should my guessing be wrong, still the code above can give you some suggestions as to the date value issue
This code is working for me:
Sub Demo()
Dim wb As Workbook
Dim txtStartDate As Date, txtEndDate As Date
Set wb = ActiveWorkbook
Set src = wb.Sheets("Request Log Extract")
Set dest = wb.Sheets("Resolution Time Performance")
srcRow = src.Cells(src.Rows.Count, "K").End(xlUp).Row
destRow = dest.Cells(dest.Rows.Count, "E").End(xlUp).Row + 1
txtStartDate = "05/13/2016"
txtEndDate = "05/18/2016"
For i = 2 To srcRow
If src.Range("K" & i).Value >= txtStartDate And src.Range("K" & i).Value <= txtEndDate Then
src.Range("K" & i).Copy Destination:=dest.Range("E" & i)
End If
Next
End Sub

How to assign value from a named range in one worksheet to a cell in the active worksheet?

I am trying to archive data from formatted worksheet called BOD_Labsheet to one called Data. I have done something similar using UserForms but am encountering problems here.
When I run the macro, I get the error "Method 'Range' of object _Worksheet failed" on line
dataWorksheet.Cells(emptyRow, 2) = bodWorksheet.Range("BOD_Lab_Date").Value
The Data worksheet is active when I do the copying.
Should I simply copy all the values from BOD_Labsheet to an array, activate the Data Worksheet and recopy values?
Here is the complete code:
Sub Submit_BOD()
'
' Submit_BOD Macro
'
Dim dataWorksheet As Worksheet, bodWorksheet As Worksheet, suspendedSolidsWorksheet As Worksheet
Dim dataSheetName As String
Dim bodSheetName As String
Dim suspendedSolidsName As String
dataSheetName = "Data"
bodSheetName = "BOD_Labsheet"
suspendedSolidsName = "Suspended_Solids_Labsheet"
Set dataWorksheet = ActiveWorkbook.Sheets(dataSheetName)
Set bodWorksheet = ActiveWorkbook.Sheets(bodSheetName)
Set suspendedSolidsWorksheet = ActiveWorkbook.Sheets(suspendedSolidsName)
Dim myRanges() As Variant
myRanges = Array("BOD_Collected_By", "BOD_Temp_Out", "BOD_Temp_IN", "BOD_Source", "BOD_Sample_Vol_4", _
"BOD_Dilution_1", "BOD_Blank_IDO_4", "BOD_Blank_FDO_4", "BOD_Sample_Vol_7", "BOD_Dilution_2", _
"BOD_Blank_IDO_7", "BOD_Blank_FDO_7", "BOD_Seed_IDO_13", "BOD_Seed_FDO_13", "BOD_Seed_IDO_14", _
"BOD_Seed_FDO_14", "BOD_Influent_IDO_15", "BOD_Influent_FDO_15", "BOD_Influent_IDO_16", _
"BOD_Influent_FDO_16", "BOD_Effluent_IDO_20", "BOD_Effluent_FDO_20", "BOD_Effluent_IDO_21", "BOD_Effluent_FDO_21", _
"In_BOD_Concentration", "Out_BOD_Concentration")
'Make Data Sheet active
dataWorksheet.Activate
Dim myDate As Date
myDate = DateValue(bodWorksheet.Range("BOD_Lab_Date").Value)
Dim yearAsString As String, monthAsString As String, dayAsString As String
yearAsString = Format(myDate, "yyyy")
monthAsString = Format(myDate, "mm")
dayAsString = Format(myDate, "dd")
Dim reportNumberText As String
reportNumberText = "NP" & yearAsString & monthAsString & dayAsString
Debug.Print "reportNumberText = "; reportNumberText
'Determine emptyRow
Dim emptyRow As Integer
emptyRow = WorksheetFunction.CountA(Range("A:A")) + 1
'Transfer information
'Sample Number
dataWorksheet.Cells(emptyRow, 1).Value = reportNumberText
'Date and Time Collected
dataWorksheet.Cells(emptyRow, 2) = bodWorksheet.Range("BOD_Lab_Date").Value
dataWorksheet.Cells(emptyRow, 3) = Format(bodWorksheet.Range("BOD_Collection_Date").Value, "dd-mmm-yyyy")
dataWorksheet.Cells(emptyRow, 4) = Format(bodWorksheet.Range("BOD_Read_On_Date").Value, "dd-mmm-yyyy")
Dim i As Integer, j As Integer
For i = LBound(myRanges) To UBound(myRanges)
j = i + 4
dataWorksheet.Cells(emptyRow, j) = bodWorksheet.Range(myRanges(i)).Value
Debug.Print "dataWorksheet.Cells(" & emptyRow & "," & j & ") " & dataWorksheet.Cells(emptyRow, j).Value
Next i
ActiveWorkbook.Save
suspendedSolidsWorksheet.Activate
Range("SS_Date").Select
End Sub
Is "BOD_LAB_DATE" more than one cell? Maybe your method usually works also, but I usually would copy a range of cells by reversing your order and using copy, like so:
bodWorksheet.Range("BOD_Lab_Date").Copy dataWorksheet.Cells(emptyRow, 2)