Copying data from/to excel worksheet using a macro - excel

I have the below code that is suppose to copy data from an excel file I receive in a email and paste it to another file on the row that has the same date. When I try and run the macro it says there is an error. Can anyone look at my code and direct me as to where my error is. I am fairly new to coding and creating macros.
Sub CopyDataToPlan()
Dim LDate As String
Dim LColumn As Integer
Dim LFound As Boolean
Dim WS As Worksheet
On Error GoTo Err_Execute
Set WS = Workbooks("McKinney Daily Census Template OCT 10.xls").Sheets("McKinney")
'Retrieve date value to search for
WS = Workbooks("McKinney Daily Census Template OCT 10.xls").Cell("B15").Value
Sheets("Input").Select
'Start at column B
LColumn = 2
LFound = False
While LFound = False
'Encountered blank cell in row 2, terminate search
If Len(Cells(2, LColumn)) = 0 Then
MsgBox "No matching date was found."
Exit Sub
'Found match in row 2
ElseIf Cells(2, LColumn) = LDate Then
'Select values to copy from "McKinney" sheet
Sheets("McKinney Daily Census Template OCT 10.xls").Select
Range("C15:I15").Select
Selection.Copy
'Paste onto "Key Indicator" sheet
Sheets("Input").Select
Cells(3, LColumn).Select
Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=False
LFound = True
MsgBox "The data has been successfully copied."
'Continue searching
Else
LColumn = LColumn + 1
End If
Wend
On Error GoTo 0
Exit Sub
Err_Execute:
MsgBox "An error occurred."
End Sub

What line generates the error? It seems that your variable LDate never recieves a date. May be instead of
WS = Workbooks("McKinney Daily Census Template OCT 10.xls").Cell("B15").Value
you meant to write
LDate = Workbooks("McKinney Daily Census Template OCT 10.xls").Cell("B15").Value
All this looks like pretty lenghty and dangerous code: why not a) get both the date from your input sheet and the data you want to copy (looks like you could put these in an array with a for loop) and then b) search for the cell that contains the date you want (1 statement) to retrieve the row of the cell that matches the date you want, and then c) loop the data from the array to the sheet.

Be more explicit with references . The code runs faster and is easier to debug:
Sub CopyDataToPlan()
Dim LDate As String
Dim LColumn As Integer
Dim LFound As Boolean
Dim WkbCensus As workbook
Dim WksCensus As worksheet
Dim WkbThis As workbook
Dim WksInput As worksheet
On Error GoTo Err_Execute
Set WkbThis = thisworkbook
Set wksInput = WkbMe.Sheets("Input")
Set WkbCensus = Workbooks("McKinney Daily Census Template OCT 10.xls")
Set WksCensus = Wkb.Sheets("McKinney")
LDate = WksCensus.Cell("B15").Value
LColumn = 2
LFound = False
While LFound = False
If Len(wksInput.cells(2, LColumn)) = 0 Then
MsgBox "No matching date was found."
Exit Sub
ElseIf wksInput.cells(2, LColumn) = LDate Then
WksCensus.Range("C15:I15").copy
wksInput.cells(3, LColumn).pastespecial Paste:=xlValues, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
LFound = True
MsgBox "The data has been successfully copied."
Else
LColumn = LColumn + 1
End If
Wend
On Error GoTo 0
Exit Sub
Err_Execute:
MsgBox "An error occurred."
End Sub

Related

VBA No Cells are found [duplicate]

This question already has answers here:
Handle "No cells were found" error when filtered range is empty
(4 answers)
Closed 9 months ago.
I used this yesterday and it ran fine but today I got a error "Run-time error '1004': No cells were found.
It bugs at
Range("A6:A30").SpecialCells(xlCellTypeVisible).Find("Temp").Select
Attached Macro Below
Sub HrsInput()
' Disable screen updating.
Application.ScreenUpdating = False
Application.DisplayAlerts = False
' Dim workbooks and sheet names.
Dim WB1, WB2 As Workbook, Year As String
Set WB1 = ActiveWorkbook
Year = Mid(ActiveSheet.Name, 10, 4)
' Copy-n-paste raw reports.
Dim FSO As Object, SourcePath As String, DestinPath As String
Set FSO = CreateObject("Scripting.FileSystemObject")
SourcePath = "\\ONTWSFS003\share\MIRALOMA\Brian\Raw Reports (FM)\*.xls"
DestinPath = "\\ONTWSFS003\share\MIRALOMA\Brian\"
FSO.CopyFile SourcePath, DestinPath
' Repeat below process until encountering an error.
Dim FileCount As Integer
Filename = Dir(SourcePath)
Do While Filename <> ""
FileCount = FileCount + 1
Filename = Dir()
Loop
For FileNum = 1 To FileCount
' Open raw report.
Workbooks.Open Filename:= _
"\\ONTWSFS003\share\MIRALOMA\Brian\*.xls"
' Capture raw report and total hours.
Set WB2 = ActiveWorkbook
Dim TotalOT As Double, BUNum As String, ReportDate() As String, WeekNum As Integer, ColNum As Integer
BUNum = Left(Range("A5"), 7)
ReportDate = Split(Range("A7"), " ")
WeekNum = WorksheetFunction.WeekNum(ReportDate(4))
Range("A:Q").UnMerge
' If not OT then skip the file.
If Not Range("A14:Z14").Find("OT1.5") Is Nothing Then
Range("A14:Z14").Find("OT1.5").Select
ColNum = Selection.Column
Range("A15:A300").Find("total").Select
Selection.Offset(0, ColNum - 1).Select
TotalOT = Selection.Value
' Fill out job title if empty.
Dim EmptyJobRng As Range, EmptyJobCell As Range
Set EmptyJobRng = Range("C15:C150").SpecialCells(xlCellTypeBlanks)
For Each EmptyJobCell In EmptyJobRng.Cells
If EmptyJobCell.Offset(0, 2) <> "" Then
EmptyJobCell = EmptyJobCell.Offset(-1, 0)
End If
Next EmptyJobCell
' Filter by temp only.
If Not Range("C15:C100").Find("*") Is Nothing Then
With Range("C14:Y150")
.AutoFilter field:=3, Criteria1:="<>"
.AutoFilter field:=1, Criteria1:="*Temp"
End With
End If
' Calculate total temp OT hours.
Dim TotalTempOT As Double, OT As Range
TotalTempOT = 0
Range("A14:Z14").Find("OT1.5").Select
Selection.Offset(1, 0).Select
Selection.Resize(150, 1).Select
Set OT = Selection.SpecialCells(xlCellTypeVisible)
For Each TempOT In OT.Cells
TotalTempOT = TotalTempOT + TempOT
Next TempOT
' Filter by BU and blank rows.
WB1.Activate
With Range("A5:BD30")
.AutoFilter field:=2, Criteria1:=BUNum
.AutoFilter field:=WeekNum + 2, Criteria1:="="
End With
' Locate temp row and week column to paste total temp OT hours.
Range("A6:A30").SpecialCells(xlCellTypeVisible).Find("Temp").Select
Selection.Offset(0, WeekNum + 1).Select
Selection = TotalTempOT
' Locate CEVA row and week column to paste total CEVA OT hours (total OT - total temp OT).
Range("A6:A109").SpecialCells(xlCellTypeVisible).Find("CEVA").Select
Selection.Offset(0, WeekNum + 1).Select
Selection = TotalOT - TotalTempOT
' Clear filters.
Sheets("Tracking " & Year & " (by BU)").ShowAllData
End If
' Delete current raw report.
WB2.Activate
ActiveWorkbook.Saved = True
ActiveWorkbook.ChangeFileAccess xlReadOnly
Kill ActiveWorkbook.FullName
WB2.Close
WB1.Activate
Next FileNum
' Update week number and weekly total OT hours.
' Week number
Range("A4").Offset(0, WeekNum).Select
Selection.Copy
Selection.Offset(0, 1).Select
Selection.PasteSpecial (xlPasteFormulas)
' Report date
Range("A5").Offset(0, WeekNum + 1).Select
Selection = "WE" & ReportDate(4)
' Weekly total OT hours
Range("A110").Offset(0, WeekNum).Select
Selection.Copy
Selection.Offset(0, 1).Select
Selection.PasteSpecial (xlPasteFormulas)
' Format Painter to new column
Range("B:B").Select
Selection.Offset(0, WeekNum - 1).Select
Selection.Copy
Selection.Offset(0, 1).Select
Selection.PasteSpecial (xlPasteFormats)
Sheets("Tracking " & Year & " (by Loc)").Select
Range("A:A").Select
Selection.Offset(0, WeekNum - 1).Select
Selection.Copy
Selection.Offset(0, 1).Select
Selection.PasteSpecial (xlPasteFormats)
' Notification when complete.
MsgBox "Data imported successfully.", vbOKOnly, "Complete"
' Enable screen updating.
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
SpecialCells(xlCellTypeVisible) raises a run-time error if there are no visible cells - one option is to ignore that error:
Dim f As range
'...
Set f = Nothing
On Error Resume Next 'ignore error if no visible cells
Set f = Range("A6:A30").SpecialCells(xlCellTypeVisible).Find("Temp")
On Error Goto 0 'stop ignoring errors
If Not f Is Nothing then
'do something with f
Else
'No visible cells, or no visible "Temp" cell...
End If
'...

Excel VBA Timeline slicerChache doesnt work with data from power query

I have a code where Pivot timeline date is changing based on the date.
Previously I had an sheet with data, but recently change the data source to from power query.
My error is that Timeline slicer doesn't work anymore.
Does anyone know why this error can occure?
ERROR : Run-time error '5' :
Invalid procedure call or argument.
Sub Datos_nustatymas()
Dim wb As Workbook, ws As Worksheet
Dim Lastrow As Long, i As Long, r As Long
Dim dt As Date, dtLast As Date, newdays As Long
Application.ScreenUpdating = False
Application.EnableEvents = False
Set wb = ThisWorkbook
wb.RefreshAll ' Refresh Pivot '
Set ws = wb.Sheets("Report")
With ws
' find end of existing data in B
Lastrow = .Cells(.Rows.Count, "B").End(xlUp).Row
' calc number of days to yesterday
dtLast = .Range("A" & Lastrow).Value2
newdays = Date - 1 - dtLast
If newdays < 1 Then
MsgBox "Report is up to date", vbExclamation
Exit Sub
Else
' extend column A to yesterday
With .Range("A" & Lastrow + 1).Resize(newdays)
.Formula = "=R[-1]C+1"
.Value = .Value
End With
End If
'update column B
For i = 1 To newdays
r = Lastrow + i
dt = .Cells(r, "A")
' this code selects a timeline date
ActiveWorkbook.SlicerCaches("NativeTimeline_VALUE_DATE").TimelineState. _
SetFilterDateRange dt, dt
' Copy/Paste details from Pivot to celected cells'
.Range("O4:Z4").Copy
.Cells(r, "B").PasteSpecial Paste:=xlPasteValuesAndNumberFormats, _
Operation:=xlNone, SkipBlanks:=False, Transpose:=False
Next
End With
Application.ScreenUpdating = True
Application.EnableEvents = True
MsgBox newdays & " days added", vbInformation
End Sub```
Fixed. Just changed "NativeTimeline_VALUE_DATE" to "Timeline_VALUE_DATE" and it worked.

Is there any way to fix this loop in VBA Excel?

I have few sheets in my Excel. I want this code to apply Some specific Sheet. Since I am not good at vba I am unable to do it. Please somebody help me. How do I add Sheet3 to 17 to this code so that code only run for these sheets.
Sub insertRowsSheets()
' Disable Excel properties before macro runs
With Application
.Calculation = xlCalculationManual
.EnableEvents = False
.ScreenUpdating = False
End With
' Declare object variables
Dim ws As Worksheet, iCountRows As Integer
Dim activeSheet As Worksheet, activeRow As Long
Dim startSheet As String
' State activeRow
activeRow = ActiveCell.Row
' Save initial active sheet selection
startSheet = ThisWorkbook.activeSheet.Name
' Trigger input message to appear - in terms of how many rows to insert
iCountRows = Application.InputBox(Prompt:="How many rows do you want to insert, starting with row " _
& activeRow & "?", Type:=1)
' Error handling - end the macro if a zero, negative integer or non-integer value is entered
If iCountRows = False Or iCountRows <= 0 Then End
' Loop through the worksheets in active workbook
For Each ws In ActiveWorkbook.Sheets
ws.Activate
Rows(activeRow & ":" & activeRow + iCountRows - 1).Insert
Range("A9").Select
Range("A8:C8").Select
Selection.Copy
Range("A9").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
Range("D8:J8").Select
Selection.AutoFill Destination:=Range("D8:J9")
Range("D8:J9").Select
Range("K8:L8").Select
Selection.Copy
Range("K9").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
Range("M8:T8").Select
Selection.AutoFill Destination:=Range("M8:T9")
Range("M8:T9").Select
Range("A8").Select
Next ws
' Move cursor back to intial worksheet
Worksheets(startSheet).Select
Range("A8").Select
' Re-enable Excel properties once macro is complete
With Application
.Calculation = xlCalculationAutomatic
.EnableEvents = True
.ScreenUpdating = True
End With
End Sub
Update Worksheets
This should work the same way as before.
At least it should help you to figure out how to loop through an array of worksheet names instead of the worksheets collection.
I could not figure out the logic of copying and filling. Shouldn't you be filling as many rows as the user selected starting from the active row?
The Code
Option Explicit
Sub insertRowsSheets()
' Define Worksheet Names Array.
Dim wsNames As Variant ' Tab names, not code names.
wsNames = Array("Sheet3", "Sheet4", "Sheet5", "Sheet6", "Sheet7", _
"Sheet8", "Sheet9", "Sheet10", "Sheet11", "Sheet12", _
"Sheet13", "Sheet14", "Sheet15", "Sheet16", "Sheet17")
' Declare object variables
Dim wb As Workbook
Dim ws As Worksheet
Dim RowsCount As Long
Dim ActiveRow As Long
Dim StartSheet As String
Dim i As Long
' Define workbook.
Set wb = ThisWorkbook ' The workbook containing this code.
' State activeRow
ActiveRow = ActiveCell.Row
' Trigger input message to appear - in terms of how many rows to insert
RowsCount = Application.InputBox(Prompt:="How many rows do you want to insert, starting with row " _
& ActiveRow & "?", Type:=1)
' Error handling - end the macro if a zero, negative integer or non-integer value is entered
If RowsCount = False Or RowsCount <= 0 Then Exit Sub
' Loop through the worksheets.
For i = LBound(wsNames) To UBound(wsNames)
With wb.Worksheets(wsNames(i))
.Rows(ActiveRow & ":" & ActiveRow + RowsCount - 1).Insert
.Range("A9:C9").Value = .Range("A8:C8").Value
.Range("D8:J8").AutoFill Destination:=.Range("D8:J9")
.Range("K9:L9").Value = .Range("K8:L8").Value
.Range("M8:T8").AutoFill Destination:=.Range("M8:T9")
End With
Next i
End Sub
' Loop through the worksheets in active workbook
For i = 3 To 17 Step 1 'This runs from the 3rd Sheet to the 17th irrespective of the name. Use array method if the sheets are mixed up
If WorksheetIDExists(i, ActiveWorkbook) Then
Set ws = ActiveWorkbook.Worksheets(i)
With ws
.Rows(activeRow & ":" & activeRow + iCountRows - 1).Insert '<- Kindly note that, if the active row is above A8, the whole script becomes a mess
.Range("A8:C8").Copy
.Range("A9").PasteSpecial Paste:=xlPasteValues
.Range("D8:J9").FillDown
.Range("K8:L8").Copy
.Range("K9").PasteSpecial Paste:=xlPasteValues
.Range("M8:T8").FillDown
.Range("A8").Select
End With
End If
Next i
Add this Function as well.
Function WorksheetIDExists(shtid As Integer, wb As Workbook) As Boolean
Dim sht As Worksheet
On Error Resume Next
Set sht = wb.Worksheets(shtid)
On Error GoTo 0
WorksheetIDExists = Not sht Is Nothing
End Function

Search through rows in entire column

I'm writing a simple Excel VBA program to search through the entire client database, looking for the specific record. While doing this, I've encountered a problem - after encountering first match, it does the instructions well and stops.
The database consists of 500+ rows and looks like this:
Column A Column B Column C Column D
Name xxxx yyy zzzz
Here's some simplified code
Sub Analizuj_1_Click()
Dim SearchName As String
Dim CColumn As Integer
Dim Match As Boolean
Dim CRow As Integer
Dim CRowPaste As Integer
On Error GoTo Err_Execute
LDate = Range("NazwaKlienta").Value
Sheets("2019").Select
'Starting in Column A, Row 2'
LColumn = 1
LRow = 2
LRowPaste = 2
LFound = False
While LFound = False
'Found a blank cell -> terminate'
If Len(Cells(CRow, 1)) = 0 Then
MsgBox "Klient nie ma zaległości"
Exit Sub
'Found Match
Szukaj: ElseIf Cells(CRow, 1) = SearchName Then
Cells(CRow, 1).EntireRow.Select
Selection.Copy
Sheets("test").Select
Cells(CRowPaste, 1).Select
Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=False
LFound = True
CRowPaste = CRowPaste + 1
Sheets("2019").Select
'Continuation"
ElseIf Cells(CRow, 1).Value > 0 Then
CRow = CRow + 1
GoTo Szukaj
End If
Wend
Exit Sub
Err_Execute:
MsgBox "Blad."
End Sub
Even If I try to continue searching through Start statement, it stops at the first found match. I tried to experiment with other methods and still the same problem.
Inb4 I know, selecting is not the most efficient method for anything

Connect newly added Sheet to existing one

This is my first post in Stack Overflow so any mistake I make please just ignore.
So i made an button which runs the macro of an application inputbox, the name you enter in the inputbox will create a new sheet with the name you entered, it also will create a table on the new sheet. The name you put on the inputbox are the clients that newly came so i will have specific sheet with table for every client that comes.
On the other hand I got the Workers which will receive incomes from clients, I Got 4 Workers which have their own Sheet and Table of Incomes and Outcomes.
Now the question i am getting to is that, is it possible to creade a code on VBA that will say: If on the new sheet (inside the table, specificly: K8:K23, K28:K43, K49:K64) the name of the Worker is inserted, copy the name of the client and paste it into the existing sheet of the Worker.
The code i tried but did not work: (Only Check the First Sub and the end of line, the between code is just a bunch of macro for table to be created, that parts work, the problem of my code which is located at the end is that it does nothing, and yes I did an commend to the codes on purpose)
Sub KerkimiKlientit()
Dim EmriKlientit As String
Dim rng As Range, cel As Range
Dim OutPut As Integer
retry:
EmriKlientit = Application.InputBox("Shkruani Emrin e Klientit", "Kerkimi")
If Trim(EmriKlientit) <> "" Then
With Sheets("Hyrjet").Range("B10:B200")
Set rng = .Find(What:=EmriKlientit, _
After:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not rng Is Nothing Then
sheet:
Flag = 0
Count = ActiveWorkbook.Worksheets.Count
For i = 1 To Count
WS_Name = ActiveWorkbook.Worksheets(i).Name
If WS_Name = EmriKlientit Then Flag = 1
Next i
If Flag = 1 Then
ActiveWorkbook.Sheets(EmriKlientit).Activate
Exit Sub
Else
Sheets.Add(, Sheets(Sheets.Count)).Name = EmriKlientit
Call KrijimiTabeles(EmriKlientit)
Exit Sub
End If
Else
OutPut = MsgBox("Klienti nuk u gjet", vbRetryCancel + vbInformation, "Provoni Perseri")
If (OutPut = vbRetry) Then
GoTo retry:
ElseIf (OutPut = vbCancel) Then
Exit Sub
End If
Exit Sub
End If
End With
End If
If userInputValue = "" Then
OutPut = MsgBox("Rubrika e Emrit e zbrazet", vbRetryCancel + vbExclamation, "Gabim")
If (OutPut = vbRetry) Then
GoTo retry:
ElseIf (OutPut = vbCancel) Then
Exit Sub
End If
Else
GoTo retry:
End If
End Sub
Sub KrijimiTabeles(EmriKlientit As String)
'
' KrijimiTabeles Macro
'
'This was just an middle code, it was too long so I did not paste it. Not an important part tho.
'This is the part that does not work, it just does nothing for some reason, there are multiple codes here and I tried them all.
'Sub Formula(EmriKlientit As String, ByVal Target As Range)
'ActiveWorkbook.Sheets(EmriKlientit).Activate
'If Not Application.Intersect(Range("K8:K23"), Range(Target.Adress)) Is Nothing Then
'Call Formula1
'End If
'End Sub
'Dim LR As Long, i As Long
'Application.ScreenUpdating = False
'Dim Rng As Range
'For Each Rng In Range("K8:K23")
'Select Case Rng.Value
'Case "M"
'Worksheets(EmriKlientit).Range("K2").Copy
'Worksheets("Mustafa").Range("K6").PasteSpecial Paste:=xlPasteFormulas
'End Select
'Next Rng
'Application.ScreenUpdating = True
'For Each cel In Rng
'If cel.Value = "M" Then
'Worksheets(EmriKlientit).Range("K2").Copy
'Worksheets("Mustafa").Range("K6").PasteSpecial Paste:=xlPasteFormulas
'End If
'Next cel
'ActiveWorkbook.Sheets(EmriKlientit).Activate
'If Not Application.Intersect(Range("K8:K23"), Range(Rng.Adress)) Is Nothing Then
'With Sheets(EmriKlientit)
'With .Range("K8:K23")
'If .Text = "M" Then
'Worksheets(EmriKlientit).Range("K2").Copy
'Worksheets("Mustafa").Range("K6").PasteSpecial Paste:=xlPasteFormulas
'End If
'End With
'End With
'End If
'Flag = 0
'Count = ActiveWorkbook.Worksheets.Count
'For i = 1 To Count
'WS_Name = ActiveWorkbook.Worksheets(i).Name
'If WS_Name = EmriKlientit Then Flag = 1
'Next i
'If Flag = 1 Then
'ActiveWorkbook.Sheets(EmriKlientit).Activate
'For Each Cell In Sheets(EmriKllientit).Range("K8:K23")
'If Cell.Value = "M" Then
'Range("K2").Copy
'Worksheets("Mustafa").Range("K6").PasteSpecial Paste:=xlPasteFormulas
'End If
'Next
'End If
End Sub
Thank you
I hope I was clear enough,
Any help would be appreciated.
Welcome to StackOverflow - i agree that your question can be a bit more specific...
I think what you are trying to achieve is something between this lines:
Dim wsClient As Worksheet, wsMustafa As Worksheet
Dim i As Long
Dim fRow As Long, lRow As Long
Set wsClient = ActiveWorkbook.Sheets("Client")
Set wsMustafa= ActiveWorkbook.Sheets("Mustafa")
'you can assign this through better ways, but to start with...
fRow = 8
lRow = 23
For i = fRow To lRow
If wsClient.Range("K" & i).Value = "M" Then
wsMustafa.Range("K6").Value = wsClient.Range("K" & i).Value 'or .Formula if that's what you want
End If
Next i
Hope this helps, good luck.

Resources