Script Runs but doesn't do anything - vba

The script runs without errors but it doesn't do whats its supposed to do, In fact it doesn't change anything in the documents. I test a part and the testing software spits out 4 workbooks that are saved in a folder named Location 1,2,3,4. Then i open a template, "alpha" in the script, that uses data from the previous workbook to show averages and to show tread of data. The macro is then activated by a button and its supposed to paste in the alpha workbook to the next empty row. The rows are 6 cells apart and 3 cells across.
Apperently i need 10 rep before pictures so heres a link to the picture.... In the picture One test is done, i have a macro for one test (row) but i cant get it to repeat and paste to the next empty down. If there is a better way of doing this please let me know haha.
https://drive.google.com/file/d/0B9n6BtJ4Med8NlVGa2FySzEtMGM/view?usp=sharing
Sub DataTransfer()
'simplified to 2 workbooks
Dim w As Workbook 'Test_Location 1
Dim Alpha As Workbook 'Template
Dim Emptyrow As Range
Set w = Workbooks.Open("C:\Users\aholiday\Desktop\FRF_Data_Macro_Insert_Test\location_1.xls")
Set Alpha = Workbooks("FRF_Data_Sheet_Template.xlsm")
Set EmptyrowC = Range("C" & Alpha.Sheets("DataInput").UsedRange.Rows.Count + 1)
w.Sheets("Data").Range("I3:K7").Copy
With Alpha.Sheets("DataInput")
EmptyrowC.PasteSpecial Paste:=xlValues, Transpose:=False
Application.CutCopyMode = True
End With
End Sub
I also tried to do a If statement but got no where with that.
Sub DataTransfer()
Application.ScreenUpdating = False
Dim w As Workbook 'Test_Location 1
Dim x As Workbook 'Test_Location 2
Dim y As Workbook 'Test_Location 3
Dim z As Workbook 'Test_Location 4
Dim Alpha As Workbook 'Template
Dim Emptyrow As Long 'Next Empty Row
Set w = Workbooks.Open("C:\Users\aholiday\Desktop\FRF_Data_Macro_Insert_Test\location_1.xls")
Set x = Workbooks.Open("C:\Users\aholiday\Desktop\FRF_Data_Macro_Insert_Test\location_2.xls")
Set y = Workbooks.Open("C:\Users\aholiday\Desktop\FRF_Data_Macro_Insert_Test\location_3.xls")
Set z = Workbooks.Open("C:\Users\aholiday\Desktop\FRF_Data_Macro_Insert_Test\location_4.xls")
Set Alpha = Workbooks("FRF_Data_Sheet_Template.xlsm")
If Columns("C").Value = "" Then
Alpha.Sheets("DataInput").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Value = w.Sheets("Data").Range("I3:K7").Value
Alpha.Sheets("DataInput").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Value = x.Sheets("Data").Range("I3:K7").Value
Alpha.Sheets("DataInput").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Value = y.Sheets("Data").Range("I3:K7").Value
Alpha.Sheets("DataInput").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Value = z.Sheets("Data").Range("I3:K7").Value
w.Close False
x.Close False
y.Close False
z.Close False
End If
Application.ScreenUpdating = True
End Sub

Something like this:
Option Explicit
Sub DataTransfer()
Const FPATH As String = "C:\Users\aholiday\Desktop\FRF_Data_Macro_Insert_Test\"
Application.ScreenUpdating = False
Dim wb As Workbook
Dim shtAlpha As Worksheet 'Template
Dim locs, loc
Dim rngDest As Range
locs = Array("location_1.xls", "location_2.xls", _
"location_3.xls", "location_4.xls")
Set shtAlpha = Workbooks("FRF_Data_Sheet_Template.xlsm").Sheets("DataInput")
'set the first data block destination
Set rngDest = shtAlpha.Cells(Rows.Count, "C").End(xlUp).Offset(1, 0).Resize(5, 3)
For Each loc In locs
Set wb = Workbooks.Open(Filename:=FPATH & loc, ReadOnly:=True)
rngDest.Value = wb.Sheets("Data").Range("I3:K7").Value
wb.Close False
Set rngDest = rngDest.Offset(0, 3) 'move over to the right 3 cols
Next loc
Application.ScreenUpdating = True
End Sub
I'm not sure what you mean to do with that check on Column C, so I left that out...

I've made a number of (reasonable...?) assumptions and rewrote the first code to use the variables that are set and define the specific workbook that various range(s) originate on.
Sub DataTransfer()
Dim w As Workbook 'Test_Location 1
Dim x As Workbook 'Test_Location 2
Dim y As Workbook 'Test_Location 3
Dim z As Workbook 'Test_Location 4
Dim Alpha As Workbook 'Template
Dim EmptyrowC As Range, EmptyrowF As Range, EmptyrowI As Range, EmptyrowL As Range
Application.ScreenUpdating = False
Set w = Workbooks.Open("C:\Users\aholiday\Desktop\FRF_Data_Macro_Insert_Test\location_1.xls")
Set x = Workbooks.Open("C:\Users\aholiday\Desktop\FRF_Data_Macro_Insert_Test\location_2.xls")
Set y = Workbooks.Open("C:\Users\aholiday\Desktop\FRF_Data_Macro_Insert_Test\location_3.xls")
Set z = Workbooks.Open("C:\Users\aholiday\Desktop\FRF_Data_Macro_Insert_Test\location_4.xls")
Set Alpha = Workbooks("FRF_Data_Sheet_Template.xlsm")
With Alpha.Sheets("DataInput")
Set EmptyrowC = .Cells(Rows.Count, "C").End(xlUp).Offset(1, 0)
Set EmptyrowF = .Cells(Rows.Count, "F").End(xlUp).Offset(1, 0)
Set EmptyrowI = .Cells(Rows.Count, "I").End(xlUp).Offset(1, 0)
Set EmptyrowL = .Cells(Rows.Count, "L").End(xlUp).Offset(1, 0)
w.Sheets("Data").Range("I3:K7").Copy Destination:=EmptyrowC
x.Sheets("Data").Range("I3:K7").Copy Destination:=EmptyrowF
y.Sheets("Data").Range("I3:K7").Copy Destination:=EmptyrowI
z.Sheets("Data").Range("I3:K7").Copy Destination:=EmptyrowL
w.Close False
x.Close False
y.Close False
z.Close False
End With
Application.ScreenUpdating = True
End Sub
It's not 100% clear on whether you absolutely require a Range.PasteSpecial method so you get yo started, I've opted for the simpler Range.Copy method. If this is insufficient, then a direct value transfer would be preferred to a Copy, PasteSpecial, Values.

Related

Copy and past with matching

I need to use a macro that will copy and paste an entire row based on whether the text of a cell matches another. I looked for something similar on the site but was not able to find something that could help. I'll outline the process I am trying to do:
Copy and paste a list of program names (the number of names can vary) from one sheet to another. (this one I have already completed)
Check each program name (number of programs can vary) individually to see if it matches a separate list on a separate sheet.
If it matches, copy and paste the entire row, if it doesn't, move to the next.
I tried using if and then statements, but I was having issues trying to loop it (if thats the correct term). The size of the list can vary, so making sure that this is taking into account in the macro is important. Here is what I have so far:
Copy and paste the initial list function
Sub Report_P1()
Dim wsPivot As Worksheet: Set wsPivot = ThisWorkbook.Sheets("Pivot")
Dim wsReport As Worksheet: Set wsReport = ThisWorkbook.Sheets("Report")
wsPivot.Select
Range("A4", Range("A65536").End(xlUp)).Select
Application.CutCopyMode = False
Selection.Copy
wsReport.Select
Range("A3").Select
ActiveSheet.Paste
End Sub
The filter tool I need help with
Sub Report_P2()
Dim i As Integer
Dim j As Integer
Dim wsReport As Worksheet: Set wsReport = ThisWorkbook.Sheets("Report")
Dim wsData As Worksheet: Set wsData = ThisWorkbook.Sheets("Data")
For i = 1 To 10
If wsReport.Cells(i, 1) = wsData.Cells(i, 1) Then
wsData.Select
Range(i).Select
'Application.CutCopyMode = False
Range(i).Copy
wsReport.Select
Range(i).Select
ActiveSheet.Paste
End If
Next i
End Sub
Thank you for your help!
Sub Report_P2()
Dim i As Integer
Dim j As Integer
Dim wsReport As Worksheet: Set wsReport = ThisWorkbook.Sheets("Report")
Dim wsData As Worksheet: Set wsData = ThisWorkbook.Sheets("Data")
For i = 1 To 10
If wsReport.Cells(i, 1) = wsData.Cells(i, 1) Then
wsData.Select
Rows(i).Select
Selection.Copy
wsReport.Activate
Range("A" & i).Activate
ActiveSheet.Paste
End If
Application.CutCopyMode = False
Next i
End Sub
Or more concisely:
For i = 1 To 10
If wsReport.Cells(i, 1) = wsData.Cells(i, 1) Then
wsData.Rows(i).Copy Destination:=wsReport.Range("A" & i)
End If
Next i

Vba copy row to another workbook based on condition

I have 2 wb and need to copy value to another wb based on condition:
If the value in the column F of wb2 appears in column F of wb1, then I need to copy value in the column G of wb2 to column G of wb1. The code is below:
Dim LtRow As Long
Dim m As Long, n As Long
With wb2.Worksheets.Item(1)
LtRow = .Cells(.Rows.Count, "G").End(xlUp).Row
End With
With ThisWorkbook.Sheets.Item(2)
n = .Cells(.Rows.Count, "G").End(xlUp).Row + 1
End With
For m = 1 To LtRow
With wb2.Worksheets.Item(1)
If .Cells(m, 6).Value = ThisWorkbook.Sheets.Item(2).Cells(m, 6).Value Then
.Rows(m).Copy Destination:=ThisWorkbook.Sheets.Item(2).Range("G" & n)
n = n + 1
End If
End With
Next m
I don't know why the code didn't work at all! Where is the problem in my code?
EDIT:
To see what your excel files look like wasn't an option for what you are trying to do. Especially because in you have many empty rows. Anyway, this works for me:
Sub CopyConditions()
Dim Wb1 As Workbook
Dim Wb2 As Workbook
Dim Wb1Ws2 As Worksheet
Dim Wb2Ws1 As Worksheet
Set Wb1 = ThisWorkbook
Set Wb1Ws2 = ThisWorkbook.Sheets("Differences")
'open the wb2
Dim FullFilePathAndName As Variant
Dim StrOpenFileTypesDrpBx As String
Let StrOpenFileTypesDrpBx = "xls (*.xls),*.xls,CSV (*.CSV),*.CSV,Excel (*.xlsx),*.xlsx,OpenOffice (*.ods),*.ods,All Files (*.*),*.*,ExcelMacros (*.xlsm),.xlsm"
Let FullFilePathAndName = Application.GetOpenFilename(StrOpenFileTypesDrpBx, 1, "Compare this workbook ""(" & Wb1.Name & ")"" to...?", , False) 'All optional Arguments
If FullFilePathAndName = False Then
MsgBox "You did't select a file!", vbExclamation, "Canceled"
Exit Sub
Else
Set Wb2 = Workbooks.Open(FullFilePathAndName)
Set Wb2Ws1 = Wb2.Sheets("Sheet1")
End If
Dim rCell As Range
Dim sCell As Range
'loop through each cell in column F until row30 because with the empty cells in the column we can't use Rows.count
For Each rCell In Wb1Ws2.Range(Wb1Ws2.Cells(1, 6), Wb1Ws2.Cells(30, 6)) 'Wb1Ws2.Cells(Wb1Ws2.Rows.Count, 6).End(xlUp))
'if the cell column F is equal to a cell in wb2 sheet1 column L
For Each sCell In Wb2Ws1.Range(Wb2Ws1.Cells(3, 12), Wb2Ws1.Cells(Wb2Ws1.Rows.Count, 12).End(xlUp))
If sCell = rCell Then
rCell.Offset(0, 1) = sCell.Offset(0, 1)
End If
Next sCell
Next rCell
End Sub
How does it go for you?

Excel VBA - Copy Sheet to new workbook X times

I need to copy the same worksheet X times (x = sheet2 row A) into a new workbook.
For each copy I need to:
1.Change a drop down to display the next value
2.Do a Refresh (Workbook is connected to a database which pulls different information based on the value of the drop down and is not automatically refreshed)
3.Copy just the values (no formulas)
Rename the sheet to the value of the drop down.
Save all of the copied worksheets into 1 workbook
My code (below) which is called on a button press currently saves the sheet X times based on sheet2 rowA (as intended).
It is missing steps 1,2,4 and 5
The code I have at the moment (called on button click)
Dim x As Integer '~~>Loop counter
Dim WS As Worksheet
Dim LastCellA As Range, LastCellB As Range
Dim LastCellRowNumber As Long
Set WS = Worksheets("Sheet2") '~~>Sheet with names
With WS
Set LastCellA = .Cells(.Rows.Count, "A").End(xlUp) '~~>Column with names.
'~~>This needs to be changed to find the range as data may not start at A1
x = Application.WorksheetFunction.Max(LastCellA.Row)
End With
For numtimes = 1 To x
ActiveWorkbook.Sheets("Sheet1").Copy _
After:=ActiveWorkbook.Sheets(Worksheets.Count)
'~~>Copy values only
ActiveSheet.UsedRange.Value = ActiveSheet.UsedRange.Value
Next
Still... I'm not sure of the point that you "Import" different values based on a drop down. That may be a different macro for loding the data. Then you need to call that macro instead of the .RefreshAll.
Sub test()
Dim uRow As Long, lRow As Long, i As Long
Dim wb As Workbook, ws As Object
With ThisWorkbook
Set ws = .Sheets("Sheet2")
With ws
uRow = .Cells(.Rows.Count, "A").End(xlUp).End(xlUp).Row
lRow = .Cells(.Rows.Count, "A").End(xlUp).Row
End With
Set wb = Workbooks.Add
For i = uRow To lRow
.Sheets("Sheet1").Range("M1").Value = ws.Cells(i, 1).Value '<~~~ this should change the dropdown
Calculate
.RefreshAll
.Sheets("Sheet1").Copy , wb.Sheets(wb.Sheets.Count)
wb.Sheets(wb.Sheets.Count).Name = ws.Cells(i, 1).Value
Next
Application.DisplayAlerts = False
wb.Sheets(1).Delete
Application.DisplayAlerts = True
For Each ws In wb.Sheets
ws.UsedRange.Value = ws.UsedRange.Value
Next
End With
End Sub
EDIT:
If you get trouble with the Sheet2 Column A List (cus it contains empty cells resulting of formulas) you may try a different approach:
Sub test()
Dim wb As Workbook, ws As Worksheet
Dim xVal As Variant
With ThisWorkbook
Set ws = .Sheets("Sheet2")
Set wb = Workbooks.Add
For Each xVal In Intersect(ws.Range("A:A"), ws.UsedRange).Value
If Len(xVal) Then
.Sheets("Sheet1").Range("M1").Value = xVal
Calculate
.RefreshAll
.Sheets("Sheet1").Copy , wb.Sheets(wb.Sheets.Count)
wb.Sheets(wb.Sheets.Count).Name = ws.Cells(i, 1).Value
wb.Sheets(wb.Sheets.Count).UsedRange.Value = wb.Sheets(wb.Sheets.Count).UsedRange.Value
End If
Next
Application.DisplayAlerts = False
wb.Sheets(1).Delete
Application.DisplayAlerts = True
End With
End Sub
Based on the code you provided, I believe this is what you are looking for.
It will loop through your list, copy sheet1 to the new workbook and name the sheet.
I am not sure what you want with looping through your dropdown list.
Sub Button1_Click()
Dim wb As Workbook, Bk As Workbook
Dim WS As Worksheet, sh As Worksheet
Dim LastCellA As Long, LastCellB As Range, c As Range
Dim LastCellRowNumber As Long
Dim x As Integer '~~>Loop counter
Set wb = ThisWorkbook
Set WS = wb.Worksheets("Sheet2") '~~>Sheet with names
Set sh = wb.Sheets("Sheet1")
With WS
LastCellA = .Cells(.Rows.Count, "A").End(xlUp).Row '~~>Column with names.
'~~>This needs to be changed to find the range as data may not start at A1
Set LastCellB = .Range("A1:A" & LastCellA).SpecialCells(xlCellTypeConstants, 23)
End With
Set Bk = Workbooks.Add
For Each c In LastCellB.Cells
sh.Range("M1") = c
sh.Copy After:=Bk.Sheets(Worksheets.Count)
With ActiveSheet
'~~>Copy values only
.UsedRange.Value = .UsedRange.Value
.Name = c
End With
Next c
End Sub

type mismatch VBA checking cell value

I am trying to understand why I get Type mismatch error:
This is the function I have, basically it is copying from a worksheet to another and afterwards deleting the first character of the copied cells:
Sub copyBackFormulas()
Application.ScreenUpdating = False
Application.EnableEvents = False
'iterate through all worksheets
Dim WS_Count As Integer
WS_Count = ActiveWorkbook.Worksheets.Count
Dim I As Integer
For I = 1 To WS_Count
Dim ws1 As Worksheet
Set ws1 = ThisWorkbook.Worksheets(I)
'if sheet contains evdre
Set d = ws1.Cells.Find("EVDRE:OK")
If Not d Is Nothing Then
'copy back all formulas except from current view
Dim wsTarget As Worksheet
Set wsTarget = ws1
nameHidden = ActiveSheet.Name & "_BPCOffline"
Sheets(nameHidden).Visible = True
Dim wsSource As Worksheet
Set wsSource = Sheets(nameHidden)
For Each c In wsSource.UsedRange.Cells
If Left(c.Value, 1) = "_" Then
If Left(c.Value, 7) = "_=EVCVW" Then
Else
c.Copy wsTarget.Range(c.Address)
End If
End If
Next
'Remove underscore
For Each c In wsTarget.UsedRange.Cells
If Left(c.Value, 1) = "_" Then
c.Formula = Right(c.Value, Len(c.Value) - 1)
End If
Next
wsSource.Visible = xlSheetHidden
End If
Range("A1").Select
Next I
Application.CutCopyMode = False
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
I have several sheets that may need to be copied. The point is that I get type mismatch error on the line: If Left(c.Value, 1) = "_" Then
However, if I run the macro starting from other sheet it just works perfectly or it is only doing the right operations on one of the sheets and not the others.
I don't understand what makes it work at some point and what not.
Any input is highly appreciated
EDIT: I think the issue has to do with the fact that the macro may not find the first condition If Left(c.Value, 1) = "_" Then
You CAN'T copy paste formulas which have an error value
If you want to skip cells with errors you need another If...End if block:
If Not Iserror(c.Value) Then
...
End if
As explained by Rory in the comments

Selecting a field in macro and cutting it out in a loop

I need to select a field of cells (table) in an Excel worksheet, cut the selection out and then paste it into a new separate sheet. There are like thousand tables below one another in this worksheet and I want to automaticly cut them out and paste them into separate sheets. The tables are separated by cells with the # symbol inside but I dont know if it is helpful in any way. When I recorded this macro for the first table it run like this:
Sub Makro1()
Range("A2:AB20").Select
Selection.Cut
Sheets.Add After:=Sheets(Sheets.Count)
ActiveSheet.Paste
End Sub
Now I want to make a loop which would go through the whole worksheet, dynamically select every table which would be delimited by the # sign in a col A and paste it into new sheet. I dont want to choose exact range A2:AB20, but I want to make selection according to this # sign.
Here's a screenshot
This will populate an array with the indicies of all your hash values. This should provide you with the reference point that you need to collect the appropriate data.
Sub FindHashmarksInColumnA()
Dim c As Range
Dim indices() As Long
Dim i As Long
Dim iMax As Double
Dim ws As Worksheet
Set ws = ActiveSheet
i = 0
iMax = Application.WorksheetFunction.CountIf(ws.Range("A:A"), "#")
ReDim indices(1 To iMax)
For Each c In ws.UsedRange.Columns(1).Cells
If c.Value = "#" Then
i = i + 1
indices(i) = c.Row
End If
Next c
' For each index,
' Count rows in table,
' Copy data offset from reference of hashmark,
' Paste onto new sheet in appropriate location etc.
End Sub
Try this code. You might need to adjust the top 4 constants to your need:
Sub CopyToSheets()
Const cStrSourceSheet As String = "tabulky"
Const cStrStartAddress As String = "A2"
Const cStrSheetNamePrefix As String = "Result"
Const cStrDivider As String = "#"
Dim rngSource As Range
Dim lngMaxRow As Long, lngLastDividerRow As Long, lngRowCount As Long
Dim wsTarget As Worksheet
Dim lngCounter As Long
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
'Delete old worksheets
Application.DisplayAlerts = False
For Each wsTarget In Sheets
If InStr(wsTarget.Name, cStrSheetNamePrefix) Then wsTarget.Delete
Next
Application.DisplayAlerts = True
With Sheets(cStrSourceSheet)
Set rngSource = .Range(cStrStartAddress)
lngLastDividerRow = rngSource.Row
lngMaxRow = .Cells(Rows.Count, 1).End(xlUp).Row
End With
Set rngSource = rngSource.Offset(1)
While rngSource.Row < lngMaxRow
If rngSource = cStrDivider Then
lngCounter = lngCounter + 1
Set wsTarget = Sheets.Add(After:=Sheets(Sheets.Count))
wsTarget.Name = cStrSheetNamePrefix & " " & lngCounter
lngRowCount = rngSource.Row - lngLastDividerRow - 1
rngSource.Offset(-lngRowCount - 1).Resize(lngRowCount).EntireRow.Copy _
wsTarget.Range("A1").Resize(lngRowCount).EntireRow
lngLastDividerRow = rngSource.Row
End If
Set rngSource = rngSource.Offset(1)
Wend
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub