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

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.

Related

Create Sheets from column values, and insert values in column in specific cells on each sheet

I found a macro that reads values in Column A on "Sheets Insert", creates individual worksheets based on those values, and then copies "Template" to each new page.
Sub NewSheets()
Dim i As Integer
Dim ws As Worksheet
Dim sh As Worksheet
Set ws = Sheets("Template")
Set sh = Sheets("Sheets Insert")
Application.ScreenUpdating = 0
For i = 2 To Range("A" & Rows.Count).End(xlUp).Row
Sheets("Template").Copy Before:=sh
ActiveSheet.Name = sh.Range("A" & i).Value
Next i
End Sub
It works great.
So the next step for me is to take the value the worksheet was created from in Column A of "Sheets Insert", and insert that value at G3 of the created worksheet.
Then I need it to take the value in the same row in column B of "Sheets Insert" and copy it into C3 on that page.
So for example:
"Sheets insert"
Column A | Column B
Motor A 12345
Motor B 23456
Code creates sheet Motor A and pastes Motor A to [g3] and pastes 12345 to [c3] on Motor A sheet.
Code creates sheet Motor B and pastes Motor B to [g3] and pastes 23456 to [c3] on Motor B sheet.
And so on down the list. I searched for a couple of hours and had no luck. Hoping someone can help. Thanks.
If i understood your question you have to add two rows of the code:
Sub NewSheets()
Dim i As Integer
Dim ws As Worksheet
Dim sh As Worksheet
Set ws = Sheets("Template")
Set sh = Sheets("Sheets Insert")
Application.ScreenUpdating = 0
For i = 2 To Range("A" & rows.count).End(xlUp).Row
Sheets("Template").Copy Before:=sh
ActiveSheet.Name = sh.Range("A" & i).Value
'add code
Range("G3") = sh.Range("A" & i) 'copy name into cell G3
Range("C3") = sh.Range("B" & i) ' copy data into cell C3
Next i
End Sub
Hope this helps

VLOOKUP from another sheet, apply formula every nth row

I'm working on the below formula to Vlookup data from another sheet. The formula must be placed on the 14th column, and every 7 rows, vlookuping the first column value.
Sub test3()
'Vlookuping on Column N
Dim lastRow As Long
lastRow = Cells(Rows.Count, 14).End(xlUp).Row 'Checks last row with data
Dim cel As Range, rng As Range
Dim sheetName, lookupFrom, myRange 'variables
sheetName = "Plan2" 'the worksheet i want to get data from
lookupFrom = ActiveCell.Offset(0, -14).Address '
myRange = "'" & sheetName & "'!1:1048576"
For i = 3 To lastRow Step 7 '
Cells(i, 14).Select 'i= first value; step= lines to jump
ActiveCell.Formula = "=VLOOKUP(" & lookupFrom & ";" & myRange & "; 14; FALSE)"
Next i
End Sub
Example Sheet
I want to place the formula on the pink cells (column N), vlookuping the pink value from the first cell on another worksheet. My actual formula isn't even executing.
Try the code below, with 2 exceptions:
1.Modify "VlookRes" to your Sheet name - where you want to results to be.
2.You have Merged Cells in Column A (according to your image uploaded), you are merging Rows 2 untill 6 in column A, this means that the value of Cell A3 will be 0. If you want the values to read from the third row, start the merging from row 3 (and soon for the next values in Column A).
Option Explicit
Sub test3()
'Vlookuping on Column N
Dim ShtPlan As Worksheet
Dim ActSht As Worksheet
Dim lastRow As Long
Dim sheetName As String
Dim lookupFrom As String
Dim myRange As String
Dim i As Long
' modify this Sheet Name to your sheet name (where you want to keep your results)
Set ActSht = Sheets("VlookRes")
lastRow = ActSht.Cells(ActSht.Rows.Count, 14).End(xlUp).Row ' Checks last row with data
sheetName = "Plan2" 'the worksheet i want to get data from
Set ShtPlan = Sheets(sheetName)
myRange = "'" & sheetName & "'!1:1048576"
For i = 3 To lastRow Step 7
lookupFrom = ActSht.Cells(i, 1).Address ' ActiveCell.Offset(0, -14).Address '
Cells(i, 14).Formula = "=VLOOKUP(" & lookupFrom & "," & myRange & ", 14, FALSE)"
Next i
End Sub

Excel: comparing names in two different sheets

I have two excel sheets with about 500 rows each. Worksheet A has a name column E) and worksheet B has two name columns for small and large names(H&I). I want to create a loop that goes through and compares these columns and should it find a match paste this match onto a new worksheet.
Further clarification:
On worksheet B the two name columns are akin to Cigna and Cigna Co for example so they are not always the same name repeated, and on Worksheet A the name may be Cigna, so they are not always exact though. But the name of Worksheet A must match 1 or both names on Worksheet B.
Something like this is an easy loop and record, then see if anything from the first sheet is on the second.
Not sure what your small and large names situation is, so I checked both columns
In you VBA IDE go to the tools menu and selecte references. Select "Microstoft ActiveX data objects 2.8 Library. This will be used for the recordset.
Private Sub CommandButton1_Click()
Dim rs As New ADODB.Recordset
Dim ws As Excel.Worksheet
Dim ws2 As Excel.Worksheet
Dim lRow As Long
Dim lRowOut As Long
Set ws = ActiveWorkbook.Sheets("Sheet1")
ws.Activate
Set ws2 = ActiveWorkbook.Sheets("Sheet3")
'Add fields to your recordset for storing data.
With rs
.Fields.Append "Row", adInteger
.Fields.Append "Name", adChar, 25
.Open
End With
'Loop through and record the name
lRow = 1
Do While lRow <= ws.UsedRange.Rows.count
rs.AddNew
rs.Fields("Row").Value = lRow
rs.Fields("Name").Value = ws.Range("E" & lRow).Value
rs.Update
lRow = lRow + 1
ws.Range("A" & lRow).Activate
Loop
If rs.EOF = False Then
rs.MoveFirst
End If
'Switch to the second worksheet
Set ws = Nothing
Set ws = ActiveWorkbook.Sheets("Sheet2")
ws.Activate
'Loop through and see if anything on this sheet was on the first sheet.
lRow = 1
lRowOut = 1
Do While lRow <= ws.UsedRange.Rows.count
'Check if the column H name was recorded from the first sheet
rs.Filter = ""
rs.Filter = "Name='" & ws.Range("H" & lRow).Value & "'"
If rs.RecordCount = 0 Then
rs.Filter = ""
rs.Filter = "Name='" & ws.Range("I" & lRow).Value & "'"
If rs.RecordCount > 0 Then
'It has a date, delete the current row
ws2.Range("A" & lRowOut).Value = rs.Fields("Name").Value
lRowOut = lRowOut + 1
End If
ElseIf rs.RecordCount > 0 Then
'It has a date, delete the current row
ws2.Range("A" & lRowOut).Value = rs.Fields("Name").Value
lRowOut = lRowOut + 1
End If
lRow = lRow + 1
ws.Range("A" & lRow).Activate
Loop
End Sub
If you want to look for a part of the name as you say in your comment, you can use a like. Change the filter lines to something like this.
rs.Filter = "Name LIKE '%" & ws.Range("I" & lRow).Value & "%'"
Doing this with formulas, instead of VBA, I would stick a formula in A1 of your new workbook like the following. Assuming that your "Worksheet A" is in Book1 on Sheet1 and your H and I columns from "Worksheet B" are Book2 on Sheet1:
=if(countif([Book2]Sheet1!H:I, [Book1]Sheet1!E1)>1, [Book1]Sheet1!A1, "")
This says "If, in my columns H and I in Sheet1 of Book2 there is at last one match on the name from Cell E1 in Sheet1 of Book1, then grab the name from Cell E1 on Sheet1 of Book1"
This will leave a good number of blanks, but at that point you can just filter or sort them out.
If the requirements are more complicated than that, like any match across any of three columns, then you can just add the results of multiple CountIf() formulas and test them for > 1, or do a single Countif() for each column and then union the results, sort/filter, and Bob's your uncle.
If this is going to be something you do often, then it may be worth investing in the VBA route as that will take the little bit of manual work out of it.

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

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

VBA Code: Vlookup Sheet1 to copy and paste on Sheet 2 if Sheet 1 contains specific text

Picking your brains here. Trying to do this for days. VBA noob.
Two Sheets: Sourcesheet ("NB & COax PO Detail Test") & Outputsheet ("New build & Coax Test")
Source sheet is an organized list. POs are in Col I and each POs value is broken down by month (J,F til dec). Each row has is dedicated to a unique PO with the monthly forecast broken down by month.
Output Sheet has the POs listed in Rows and Monthly forecast in Columns. The idea is to vlookup the monthly forecast for each PO in source sheet, if the Col C (output sheet) is PO Materials or PO Labor then Vlookup, otherwise skip to next row. Vlookup has to apply the monthly forecast to each month. After each Vlookup I am trying to copy and paste the value so that there isnt too much coding leading to Excel crash. Also in the Source sheet the Col Index Num for the Output Sheet vlookup is listed above each month.
In a nutshell.
If(Or (Outputsheet.Col I ="PO Labor", Outputsheet.Col I ="PO Materials"), Vlookup(Outputsheet.ColE, SourceSheet.Range(Col I to Col AB:5000), SourceSheetR3,False), "") Copy and Paste next Column in the same row repeat until OutputSheet Col R. Copy and paste. Next row.
SourceSheet R3 is variable it changes so I want Vlookup to pick up the Column number from there as stated above each month of the Col.
(Output Sheet & Source Sheet Click the next image) http://imgur.com/SHANSLF&ydjQfb3#0
(Code) http://imgur.com/MieCu5G
Finally finished this with the help of several genereous memebers of this community and Chandoo Community. here is the final code that I put together and that actually works.
Sub MakeFormulas()
Dim SourceLastRow As Long
Dim OutputLastRow As Long
Dim sourceSheet As Worksheet
Dim outputSheet As Worksheet
Dim X As Long
Dim Z As Long
'What are the names of our worksheets?
Set sourceSheet = Worksheets("Sheet1")
Set outputSheet = Worksheets("Sheet2")
'Determine last row of source
With sourceSheet
SourceLastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
End With
With outputSheet
'Determine last row in col C
OutputLastRow = .Cells(.Rows.Count, "C").End(xlUp).Row
For y = 17 To 28 'Q to AB
For X = 2 To OutputLastRow
If InStr(1, .Range("C" & X), "PO Materials") + InStr(1, .Range("C" & X), "PO Labor") > 0 And Cells(2, y) = "Forecast" Then
'Apply formula
.Cells(X, y).Value = _
Evaluate("=VLOOKUP($E" & X & ",'" & sourceSheet.Name & "'!$A$2:$L$" & SourceLastRow & ",Match(" & Cells(1, y).Address & ",'" & sourceSheet.Name & "'!$A$1:$AD$1,0),0)")
End If
Next
Next
End With
End Sub

Resources