How to check range/column of cells based on month and copy them - excel

So essentially, what I'm trying to do is this:
------A--------B-------C-------D------
1 Date Weight Misc ID*
2 2014-06-12 210 445556
3 2014-07-13 150 546456
4 2014-08-14 265 546456
5 2014-09-15 655 655654
6 2014-10-16 87 546656
7 2014-10-17 1552 545488
8 2014-11-18 225 546545
I have a button and I want it to run a macro that checks if the dates in Column A fall within the current month. I've tried using
Month(Date)
but it checks the entire date, not the month only.
If the month in the cell in colmumn A equals the current month, I want it to copy the entire row of information corresponding to that particular cell. For example: When the current month is november, I want it to copy A8+B8+C8+D8, then I will paste that information in a whole different workbook.
Keep in mind that I'm completely new to VBA, but this is what I've come up with so far:
Sub dat()
Dim rng As Range
Dim dat As Date
dat = Month(Date)
For Each rng In Range("A2:A100")
If rng.Value = dat Then
Range("???").Copy
Range("A1").PasteSpecial
End If
Next
End Sub
Nothing really happens. If I change it to dat=Date then it only works for this particular day, and it takes forever to run through 1000 cells.
I was thinking if I could use Cells(Rows.Count, "A").End(xlUp).Value = Month(Date) somehow. Is this even possible?
EDIT: To paste in a different workbook I used the following commands:
Dim wb As Workbook
Set wb = Workbooks.Open("C:\Users\....DOCUMENT.xlsm")
And then to paste:
wb.Sheets("Sheet1").Range("A" & NextDest & ":F" & NextDest).PasteSpecial

Just change the "Destination Sheet" to the name of the sheet you want to copy to.
Sub dat()
Dim LastRow As Long
Dim CurRow As Long
Dim NextDest As Long
Dim ws As Worksheet
Set ws = Sheets("SOURCE SHEET")
LastRow = ws.Range("A" & Rows.Count).End(xlUp).Row
For CurRow = 2 To LastRow
If IsDate(ws.Range("A" & CurRow).Value) = True Then
If Month(ws.Range("A" & CurRow).Value) = Month(Date) Then
ws.Range("A" & CurRow & ":D" & CurRow).Copy
NextDest = Sheets("DESTINATION SHEET").Range("A" & Rows.Count).End(xlUp).Row + 1
Sheets("DESTINATION SHEET").Range("A" & NextDest & ":D" & NextDest).PasteSpecial
Else
End If
Else
ws.Cells(CurRow, 1).Interior.Color = RGB(255,0,0)
End If
Next CurRow
End Sub
Edit: Your DESTINATION SHEET will now add rows after the last used row. Also, the code will check if the value is a date first and will highlight if not a date.

Change this
If rng.Value = dat Then
To
If month(rng.Value) = dat Then

Related

How do I move specific valued cells in VBA?

I am working with a dataset that contains both numbers and names. In the dataset, some numbers and names are displayed and instead of manually going through thousands of rows I tried to make a script but it doesn´t happen anything.
Here is the code:
Sub MoveCells()
Dim row As Long
For row = 2 To LastRow
If Range("C" & row).Value Like "*0*" Then
Dim i As Integer
For i = 1 To 2
Range("C" & row).Insert Shift:=xlToRight
Next
End If
Next
End Sub
I am trying to move the cell that has a 0 in it, and the cell to the right of it, one step to right.
E.g. Cells C4 & D4 to D4 & E4.
I've made some adjustments to your code which will acheive the outcome you described.
Private Sub MoveCells()
Dim TargetRow As Long
Dim LastRow As Long
Dim ColumnCValue As Variant
Dim ColumnDValue As Variant
With Sheets("Sheet1")
LastRow = .Cells(.Rows.Count, 3).End(xlUp).row
End With
For TargetRow = 2 To LastRow
If Sheets("Sheet1").Range("C" & TargetRow).Value Like "*0*" Then
ColumnCValue = Sheets("Sheet1").Range("C" & TargetRow).Value
ColumnDValue = Sheets("Sheet1").Range("D" & TargetRow).Value
Sheets("Sheet1").Range("D" & TargetRow).Value = ColumnCValue
Sheets("Sheet1").Range("E" & TargetRow).Value = ColumnDValue
Sheets("Sheet1").Range("C" & TargetRow).ClearContents
End If
Next
End Sub
Now we first assign a value to for LastRow and when the If...Then statement is true, assign the values of Column C and Column D to the respective variables. Then, write those values 1 row to the right and finally clear the contents from Column C.

Finding & filling in other Excel sheets based on criteria using VBA

I have a workbook with four worksheets: Overview, apple, banana and pear.
In the sheet overview I have a 3x3 table:
In Out Extra
apple
banana
pear
Cell H5 in Overview contains a date of 2019, which can be selected via a drop-down menu
In each of the apple/banana/pear sheets, I have a 365x3 table:
In Out Extra
1-1-2019
2-1-2019
3-1-2019
.
.
.
31-12-2019
I would like to run a macro so that the In, Out and Extra values from the Overview sheet are filled in the correct worksheet and behind the correct date in that worksheet.
The goal would be that people fill in the overview sheet (In, Out and Extra values as well as a date), they run the macro, and data is automatically stored in the right cell in the right worksheet.
This is a relatively easy example, the actual workbook for which I need this macro has more that 70 "fruits".
I know the code below doesn't work, but I'll hope to show my way of thinking
Sub export()
Dim ws As Worksheet 'worksheet
Dim currentdate As Date 'datum
Dim fruit As String 'Fruit
Worksheets("Overview").Activate 'activate worksheet Overview
currentdate = ActiveSheet.Cells(H5) 'select date value
fruit = Overview.Range(“C6, C8”) 'select range of the fruits
For Each ws In Worksheets 'loop over every worksheet except the Overview sheet
If ws.Name = fruit Then 'crossreference name worksheet with fruit in Overview sheet
ws.Activate 'activating the selected worksheet
If ws.Range("A1:A365") = currentdate Then 'looking for the correct date in the selcted worksheet
fruit = ws.Name
Next ws
End Sub
Vba solution for this:
For this solution to work properly, you should make the sheets APPLE, BANANA and PEAR share same structure. In my example, all this 3 sheets have in column A the date, column B is IN, column C is OUT and column D is EXTRA
Also, in OVERVIEW sheet, make sure the terms APPLE, BANANA and PEAR are exactly equal to names of each sheet (this means no extra spaces, blanks or different chars).
And OVERVIEW must be the active sheet.
My button IMPORT is linked to this code to import data. I want to import data from 17/05/2019 (the yellow rows)
Sub IMPORT_DATA()
Application.ScreenUpdating = False
Range("B2:D4").Clear
Dim i As Long
Dim TargetRow As Long
Dim TargetSheet As String
Dim TargetDate As Date
TargetDate = Range("B6").Value
For i = 2 To Range("A" & Rows.Count).End(xlUp).Row Step 1 'i=2 because dats in OVERVIEW stars at row 2, and Column A
TargetSheet = Range("A" & i).Value
'first, we make sure the date from B6 exists in the target worksheet counting
With Application.WorksheetFunction
If .CountIf(ThisWorkbook.Worksheets(TargetSheet).Range("A:A"), TargetDate) > 0 Then
TargetRow = .Match(CDbl(TargetDate), ThisWorkbook.Worksheets(TargetSheet).Range("A:A"), 0)
Range("B" & i).Value = ThisWorkbook.Worksheets(TargetSheet).Range("B" & TargetRow).Value 'IN value
Range("C" & i).Value = ThisWorkbook.Worksheets(TargetSheet).Range("C" & TargetRow).Value 'IN value
Range("D" & i).Value = ThisWorkbook.Worksheets(TargetSheet).Range("D" & TargetRow).Value 'IN value
End If
End With
Next i
Application.ScreenUpdating = True
End sub
And after executing this code I get in OVERVIEW:
Now I want to export some values to data, and I use this code:
Sub EXPORT_DATA()
Application.ScreenUpdating = False
Dim i As Long
Dim TargetRow As Long
Dim TargetSheet As String
Dim TargetDate As Date
TargetDate = Range("B6").Value
For i = 2 To Range("A" & Rows.Count).End(xlUp).Row Step 1 'i=2 because dats in OVERVIEW stars at row 2, and Column A
TargetSheet = Range("A" & i).Value
'first, we make sure the date from B6 exists in the target worksheet counting
With Application.WorksheetFunction
If .CountIf(ThisWorkbook.Worksheets(TargetSheet).Range("A:A"), TargetDate) > 0 Then
TargetRow = .Match(CDbl(TargetDate), ThisWorkbook.Worksheets(TargetSheet).Range("A:A"), 0)
ThisWorkbook.Worksheets(TargetSheet).Range("B" & TargetRow).Value = Range("B" & i).Value 'IN value
ThisWorkbook.Worksheets(TargetSheet).Range("C" & TargetRow).Value = Range("C" & i).Value 'OUT value
ThisWorkbook.Worksheets(TargetSheet).Range("D" & TargetRow).Value = Range("D" & i).Value 'EXTRA value
End If
End With
Next i
MsgBox "data exported"
Application.ScreenUpdating = True
End Sub
And after executing code, check new data (yellow rows):
Hope this helps a litte bit and you can adapt to your needs.

Transferring Cell Values Between Worksheets | Str Looper

Intended Result
If a row in a table contains any of the listed strings in column L on Sheet1, Then copy the entire row from Sheet1 and paste the row into a duplicate table on Sheet2 (which would be blank at the beginning).
(UNINTERESTED, UNRELATED, UNDECIDED, etc...)
Then delete the entire row that was transferred from sheet 1.
After macro runs, the new transfers should not reset table on Sheet2, rather add rows on the pre-existing lines. This document would be utilized over months.
Variables
Sheet1 is named Pipeline_Input
Sheet2 is named Closed_Sheet
Sheet1 table is named tblData
Sheet2 table is named tblClosed
Images
Image 1 is the code with error
Image 2 is Sheet 1 with some picture explanation
Image 3 is Sheet 2 with some picture explanation
Current Result
Run-time error '1004':
Application-defined or object-defined error
Sub closedsheet()
Application.ScreenUpdating = False
Dim Pipeline_input As Worksheet 'where is the data copied from
Dim Closed_Sheet As Worksheet 'where is the data pasted to
Dim strPhase() As String
Dim i As Integer
Dim intPhaseMax As Integer
Dim lngLstRow As Long
Dim rngCell As Range
Dim finalrow As Integer
Dim lr As Long 'row counter
Dim Looper As Integer
intPhaseMax = 6
ReDim strPhase(1 To intPhaseMax)
strPhase(1) = "LOST"
strPhase(2) = "BAD"
strPhase(3) = "UNINTERESTED"
strPhase(4) = "UNRELATED"
strPhase(5) = "UNDECIDED"
strPhase(6) = "BUDGET"
'set variables
Set Pipeline_input = Sheet1
Set Closed_Sheet = Sheet2
lr = Range("A" & Rows.Count).End(xlUp).Row
For Looper = LBound(strPhase) To UBound(strPhase)
For i = lr To 6 Step -1
Next
If Not Sheet1.Range("L9:L300" & lngLstRow).Find(strPhase(Looper), lookat:=xlWhole) Is Nothing Then
Range(Cells(i, 1), Cells(i, 20)).Copy
Sheet2.Range("A" & Rows.Count).End(3)(2).PasteSpecial xlPasteValues
Range(Cells(i, 1), Cells(i, 20)).Delete
End If
Next
Sheet2.Select
Sheet2.columns.AutoFit
Application.CutCopyMode = False
Application.ScreenUpdating = True
End Sub
Okay, there were a plethora of issues with the code you posted, but I decided to help you out here - Notice a few things - There's no copying and pasting here - we're just transferring data.
Secondly, use easy to understand variables. lr and lngLastRow can't be distinguished from one another, so classify them by which worksheet you're getting that value from.
We create an array in one fell swoop here - Just declare a variant and place our values in. ARRAYS (TYPICALLY) START AT ZERO, NOT ONE, so our loop starts at 0 :). Again, this is what's known as best practice...
I swapped out Looper for j. Again, keep. it. simple!
EDIT: I tested this code out on a simulated workbook and it worked fine - should run into no issues for you either.
EDIT2: Also, always use Option Explicit!
Option Explicit
Sub closedsheet()
Application.ScreenUpdating = False
Dim Pipeline_Input As Worksheet 'source sheet
Dim Closed_Sheet As Worksheet 'destination sheet
Dim i As Long, j As Long, CSlastrow As Long, PIlastrow As Long
Dim strPhase As Variant
'Here we create our array
strPhase = Array("LOST", "BAD", "UNINTERESTED", "UNRELATED", "UNDECIDED", "BUDGET")
'Assign worksheets
Set Pipeline_Input = ActiveWorkbook.Worksheets("Pipeline_Input")
Set Closed_Sheet = ActiveWorkbook.Worksheets("Closed_Sheet")
PIlastrow = Pipeline_Input.Range("A" & Rows.Count).End(xlUp).Row
For j = 0 To UBound(strPhase)
For i = PIlastrow To 6 Step -1
If Pipeline_Input.Range("L" & i).Value = strPhase(j) Then
'Refresh lastrow value
CSlastrow = Closed_Sheet.Range("A" & Rows.Count).End(xlUp).Row
'Transfer data
Closed_Sheet.Range("A" & CSlastrow + 1 & ":S" & CSlastrow + 1).Value = _
Pipeline_Input.Range("A" & i & ":S" & i).Value
'Delete the line
Pipeline_Input.Range("A" & i & ":S" & i).EntireRow.Delete
End If
Next i
Next j
Closed_Sheet.Select
Closed_Sheet.Columns.AutoFit
Application.ScreenUpdating = True
End Sub

Matching two values for multiple columns. i cant figure how to approach it

i have 6 columns
Grade,Date, ID number, Grade Old, date old and ID number
I need the grade to look for value in grade old and also date old of the grade needs to be within 2 weeks of the date then the ID number is same.
for example:
if grade = A then it needs to look for A in Grade Old and also compare the dates, if the date old is 2 weeks of date then ID number stays the same.
(There can be multiple Grades i.e. Grade old can have multiple entries as A, just need to pick the right one by comparing dates.)
I have no idea how do i achieve this. I tried a few codes but in vain.
Thank you for your time. I appreciate your help.
Give this code a try. This should do what you want, based on your comments above.
Note on data structure:
Grade is in column A, Row 1 are the headers.
My sheet is called "Grades"
Change the code according to your sheet structure.
Sub grades()
Dim wb As Workbook
Dim ws As Worksheet
Dim firstrow, lastrow As Integer
Dim firstAddress As String
Dim tmpFind As Range
Dim grade As String
Dim dateLeft As Double
Dim dateOld As Double
Dim found As Boolean
Set wb = ThisWorkbook
Set ws = wb.Worksheets("Grades") 'change "Grades" to the name of your sheet
With ws
firstrow = 2
lastrow = .Range("A1000000").End(xlUp).Row
For r = firstrow To lastrow
found = False
grade = .Range("A" & r).Value
dateLeft = .Range("B" & r).Value
Set tmpFind = .Range("D" & firstrow & ":D" & lastrow).Find(grade, LookIn:=xlValues, LookAt:=xlWhole, SearchDirection:=xlNext, MatchCase:=False)
If Not tmpFind Is Nothing Then
firstAddress = tmpFind.Address
Do
dateOld = .Range("E" & tmpFind.Row).Value
'check if dateOld is within + - two weeks. if + 2 weeks not required, remove 'And dateOld <= dateLeft + 14' from below
If dateOld >= dateLeft - 14 And dateOld <= dateLeft + 14 Then
.Range("F" & tmpFind.Row).Value = .Range("C" & r).Value 'writes ID-left to ID-right
found = True
End If
Set tmpFind = .Range("D" & firstrow & ":D" & lastrow).FindNext(tmpFind)
Loop While Not tmpFind Is Nothing And tmpFind.Address <> firstAddress And found = False
End If
Next r
End With
End Sub
Are you looking for a Excel Macro to do this?
You may use the below formulae
=IF(ISERROR(MATCH(,A:A, 0)), "No Match", "Match")
=IF(G2="Match",IF(B2-E2<15,C2,F2),)
If you are looking for an excel macro then you may use try using the same sort of validation in your logic. Hope this helps.. thanks.
-Codekavi.

countif statement what wont count 00:00

Any help would be appreciated. I need the CountIf statement to count all the data points that are equal to 00:00. The column is formatted for 24hr time due to other formulas. The 00:00 is a product of an if statement. I have tried many options but it won’t calculate unless I reformat the column to general, but in doing that it messes up my time formation which I need to be 24hr format. Thanks.
Sub Sample()
Dim result As Long, firstrow As Long, lastrow As Long
Dim ws As Worksheet
Dim rng As Range
'~~> Set this to the relevant worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws
'~~> Find Lastrow in Col D
lastrow = .Range("V" & .Rows.Count).End(xlUp).Row
'~~> Set First row
firstrow = 16
'~~> Set your range
Set rng = .Range("V" & firstrow & ":V" & lastrow)
'~~> Put relevant values
.Range("U" & lastrow + 3).Value = "No Slip Time"
.Range("V" & lastrow + 3).Value = _
Application.WorksheetFunction.CountIf(rng, "*00:00")
End With
End Sub
Notes:
The string "00:00" and time 0 are not the same.
Date and time is a number where 0 is midnight, 1 a day and 0.5 is 12 hours.
Based on your comments you have the following formula in column v, =IF((K16="NA"),"00:00",IF(K16<>"na",K16)), use this instead.
=IF(Upper(K16)="NA",0,K16)
If you have #N/A in cell K16 you need to replace the above "NA" with NA().
Also once done you can use the countif as follows.
Application.WorksheetFunction.CountIf(rng.value2 , "0")

Resources