I have two files. 1 file contains data with tabs named as company. The second file is to analyse the companies and I have there also tabs which are named in the same name as in tabs in file with copmanies data. In the file where I analyse data I have tab macro where I put information requires for macro. Companies name, file names. When the new copamny comes or the old one will disappear I want to do the same in macro as macro takes information from the tab macro from cells. Now what I want to have is that macro will copy for company A from file with companies data and paste into file with companies analyse. I have used to that loop FOR TO as then macro will copy and paste company A and then B,then C and so on and so forth. The macro is below. First part works. Opens file with data and active however then it doesnt work. I think I mixed variables but I have no idea how to fix it. Any ideas?
Sub CopyData()
Workbooks.Open Range("A10").Value
Dim wb As Workbook
Dim wbk As Workbook
Dim i As Integer
Dim FieldAVal As Worksheet
Dim FieldBVal As Worksheet
Dim Iter As Integer
For Each wb In Application.Workbooks
If wb.Name Like "*Reconciliation*" Then
wb.Activate
Exit For
End If
Next wb
Set wbk = Workbooks(Range("A9").Value)
Sheets("Macro").Select
Range("B6").Select
'define ranges with column numbers
Iter = Cells(1, 3).Value
For i = 1 To Iter
FieldAVal.Name = Cells(i + 14, 2).Value
FieldBVal.Name = Cells(i + 14, 3).Value
Workbooks(wbk).Worksheets(FieldBVal).Range("A1:V1000").Copy _
Destination:=ThisWorkbook.Worksheets(FieldAVal).Range("B2")
Next i
End Sub
I am not sure understanding
Public Sub CopyData()
On Error GoTo ErrHANDLER
Dim wb As Workbook
Dim wbk As Workbook
Dim i As Integer
Dim FieldAVal As Worksheet
Dim FieldBVal As Worksheet
Dim Iter As Integer
'add Variables
Dim secondFileName As String
Dim wbSecondFile As Workbook
Dim openedworkbookNameB As String
Dim openedworkbook As Worksheet
Dim pasteWorksheet As Worksheet
secondFileName = Range("A10").Value
'already opened workbook
openedworkbookNameB = Range("A9").Value
Set wbSecondFile = Workbooks.Open(secondFileName)
'Fail to open
If wbSecondFile Is Nothing Then
Exit Sub
End If
Set openedworkbook = Workbooks(openedworkbookNameB)
'no workbook
If openedworkbook Is Nothing Then
Exit Sub
End If
Call ThisWorkbook.Activate
ThisWorkbook.Sheets("Macro").Select
'ActiveSheet == "Macro" sheet
ActiveSheet.Range("B6").Select
Iter = VBA.Val(ActiveSheet.Cells(1, 3).Value)
For i = 1 To Iter
FieldAVal.name = ActiveSheet.Cells(i + 14, 2).Value
FieldBVal.name = ActiveSheet.Cells(i + 14, 3).Value
Set pasteWorksheet = ThisWorkbook.Worksheets(FieldAVal)
If Not pasteWorksheet Is Nothing Then
openedworkbook.Worksheets(FieldBVal).Range("A1:V1000").Copy _
Destination:=pasteWorksheet.Range("B2")
End If
Set pasteWorksheet = Nothing
Next i
Exit Sub
ErrHANDLER:
'When Raise error
Debug.Print Err.Number & " : " & Err.Description
'debug point Here
'press "F8" Key to Run a Macro Line by Line
Stop
Resume
End Sub
Related
I have macro that finds the value "a" and replaces with value "b" across multiple worksheets and workbooks
the macro loops through files in folder and files in subfolders and replaces all the values it can find.
now i want the macro to return the file name in column E of the worksheet the macro is written in, ONLY IF changes where made in the file ( so if a was replaced with b return file name in colum E)
but my current code it only returns the file name of the first workbook it runs through.
my codes starts at sub search and it takes as an input sub()
Sub FindReplaceAcrossMultipleExcelWorkbooksFreeMacro(Path As String)
Dim CurrentWorkbookName As String
Dim ExcelCounter As Integer
Dim ExcelWorkbook As Object
Dim FindReplaceCounter As Integer
Dim FindandReplaceWorkbookName As String
Dim FindandReplaceWorksheetName As String
Dim LastRow As Integer
Dim oFile As Object
Dim oFolder As Object
Dim oFSO As Object
Dim Shape As Shape
Dim ws As Worksheet
Dim myrange As Range
Dim look As String
FindandReplaceWorkbookName = ActiveWorkbook.Name
FindandReplaceWorksheetName = ActiveSheet.Name
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oFolder = oFSO.GetFolder(Path)
For Each oFile In oFolder.Files 'Loop through every File in Active Workbook's folder path
If InStr(1, oFile.Type, "Microsoft Excel") <> 0 And InStr(1, oFile.Name, FindandReplaceWorkbookName) = 0 And InStr(1, oFile.Name, "~") = 0 Then 'If the File Type contains the phrase Microsoft Excel isn't the current Excel Workbook and is NOT Lock File
Set ExcelWorkbook = Application.Workbooks.Open(Path & "\" & oFile.Name) 'Open Excel Workbook
CurrentWorkbookName = ActiveWorkbook.Name 'Name of Active Excel Workbook that was opened
Application.Workbooks(CurrentWorkbookName).Activate 'Ensure open Excel Workbook is active for future reference using ActiveWorkbook
Application.ScreenUpdating = False 'Limit screen flashing when Excel Workbooks opened and when Find & Replace is completed
FindReplaceCounter = 2
LastRow = Workbooks(FindandReplaceWorkbookName).Sheets(FindandReplaceWorksheetName).Cells(Rows.Count, 1).End(xlUp).Row 'Identify Last Row in Column A
Do Until FindReplaceCounter > LastRow 'Complete the Find and Replace for all values in Column A & B
For Each ws In ActiveWorkbook.Worksheets 'Loop through every Excel Worksheet in Active Excel Workbook
Set myrange = ws.UsedRange.Find(what:="ben")
If Not myrange Is Nothing Then
Workbooks(FindandReplaceWorkbookName).Sheets(FindandReplaceWorksheetName).Range("E" & Rows.Count).End(xlUp).Offset(1, 0) = ExcelWorkbook.Name
End If
ws.Cells.Replace what:=Workbooks(FindandReplaceWorkbookName).Sheets(FindandReplaceWorksheetName).Cells(FindReplaceCounter, 1).Value, Replacement:=Workbooks(FindandReplaceWorkbookName).Sheets(FindandReplaceWorksheetName).Cells(FindReplaceCounter, 2).Value
Next ws
FindReplaceCounter = FindReplaceCounter + 1
Loop
ActiveWorkbook.Save 'Save Active Excel Workbook
ActiveWorkbook.Close 'Close Active Excel Workbook
End If
Next oFile
Application.ScreenUpdating = True 'Turn Excel ScreenUpdating back on
Set ExcelWorkbook = Nothing
Set oFSO = Nothing
Set oFolder = Nothing
Set oFile = Nothing
Exit Sub
End Sub
Sub Search()
FindReplaceAcrossMultipleExcelWorkbooksFreeMacro (Cells(2, 3).Value)
MsgBox "The Find and Replace has been completed."
End Sub
If I understand you correctly, maybe the code below can help you to compare it with your case.
Sub test()
Dim rg As Range: Dim wb As Workbook
Dim oFSO: Dim oFolder: Dim oFile
Dim fn As String: Dim sh As Worksheet: Dim cell As Range
Application.ScreenUpdating = False
Set wb = ActiveWorkbook
With wb.Sheets("Sheet1")
Set rg = .Range("A2", .Range("A" & Rows.Count).End(xlUp))
.Range("E:E").ClearContents
End With
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oFolder = oFSO.GetFolder("D:\test")
For Each oFile In oFolder.Files
fn = oFile.Name
If InStr(fn, "test") Then GoTo nextfile:
Workbooks.Open oFile
With ActiveWorkbook
For Each sh In .Worksheets
For Each cell In rg
If Not sh.Cells.Find(cell.Value) Is Nothing Then
sh.UsedRange.Replace what:=cell.Value, Replacement:=cell.Offset(0, 1).Value, LookAt:=xlWhole
wb.Sheets("Sheet1").Range("E" & Rows.Count).End(xlUp).Offset(1, 0).Value = _
fn & " - " & sh.Name & " : value " & cell.Value & " is replaced with " & cell.Offset(0, 1).Value
End If
Next
Next
.Close SaveChanges:=False
End With
nextfile:
Next oFile
Application.ScreenUpdating = True
End Sub
To test the code, create 3 workbooks :
Name the first wb "test.xlsm", this is the wb where the code resides. In test.xlsm sheet Sheet1, make two column header in column A and B, and name it : FIND in A1 and REPLACE in B1. Under FIND, put data such as aaa in A2, bbb in A3, ccc in A4. Under REPLACE, put data such as XXX in B2, YYY in B3, ZZZ in B4.
Create other two workbooks, name it as you like. In each wb, put aaa and/or bbb and/or ccc to whatever cell whatever sheet as many as you like.
put test.xlsm and the other two workbooks in one folder in drive D:, name the folder "test".
Run the code in test.xlsm. Make sure that the other two workbooks is close.
There are three loops in the code.
The first is to loop to each file in test folder
The second is to loop to each sheet of that file
The third is to loop to each FIND/REPLACE value in sheet Sheet1 test.xlsm
On the first loop, it open the file / workbook (which is not test.xlsm)
then it loop to each sheet of that opened wb
on looped sheet, it loop to each data under FIND/REPLACE in sheet1 test.xlsm, and check if the looped cell value is found in the looped sheet, then it perform two process : (A) the found value is replaced with replace value (B) write the information in column E sheet1 of test.xlsm
Please note, the code doesn't write information on the looped sheet of the looped workbook which is being opened. It's just replace to a new value if the value to be replaced is found.
If you run the sub for the second time, there shouldn't be any information in column E sheet Sheet1 in test.xlsm.
Sorry for the oddly worded question. I have code (below) that creates new sheets based on column data. After the sheets are created VBA copies and pastes every row from the master sheet into the category sheet. I just want excel to save the .csv file and close. It closes but only keeps the last sheet. Is this due to it being a .csv file? If I manually Save As and convert to .xlsx then the columns remain. But I tried adding VBA code to do the same thing and it just saved an empty .xlsx file. I'm not sure what to do...
Sub Loading_Summary_Breakout()
'Prevents Clipboard Pop-up from appearing.
Application.DisplayAlerts = False
'Prevents screen flicker and makes the macro run faster.
Application.ScreenUpdating = False
'Opens Loading Summary workbook.
Workbooks.Open Filename:=Environ("USERPROFILE") & "\Dropbox (Gotham Enterprise)\Operations Management\#MASTER SCHEDULE\Shop Schedule V4\Loading Summary.csv"
Workbooks("Loading Summary.csv").Activate
Call DeleteRowsSpecialChartrs
Dim cell As Range, v
Dim SheetName As String, wb As Workbook, ws As Worksheet
Set ws = ActiveSheet
Set wb = ws.Parent
'Creates new worksheet/tab for every unique value in Column B (Customer Code Column)
For Each cell In ws.Range(ws.Range("B2"), ws.Range("B" & Rows.Count).End(xlUp)).Cells
v = cell.Value
If Len(v) > 0 Then cell.EntireRow.Range("A1:O1").Copy _
GetSheet(v, wb).Cells(Rows.Count, 1).End(xlUp).Offset(1, 0)
Next
Call DeleteDuplicates
ActiveWorkbook.Save
Application.ScreenUpdating = True
End Sub
'Return a named sheet in wb (or create if doesn't exist)
Private Function GetSheet(ByVal SheetName As String, wb As Workbook)
Dim ws As Worksheet
On Error Resume Next
Set ws = wb.Worksheets(SheetName)
On Error GoTo 0
If ws Is Nothing Then
Set ws = wb.Worksheets.Add(after:=wb.Sheets(wb.Sheets.Count))
ws.Name = SheetName
End If
Set GetSheet = ws
End Function
Public Sub DeleteRowsSpecialChartrs()
Dim rng As Range
Dim pos As Integer
Set rng = ActiveSheet.Range("B:B")
For i = rng.Cells.Count To 1 Step -1
pos = InStr(LCase(rng.Item(i).Value), LCase("/"))
If pos > 0 Then
rng.Item(i).EntireRow.Delete
End If
Next i
End Sub
Public Sub DeleteDuplicates()
Dim ws As Worksheet
Dim wkbk1 As Workbook
Dim w As Long
Set wkbk1 = Workbooks("Loading Summary.csv")
wkbk1.Activate
With wkbk1
For w = 1 To .Worksheets.Count
With Worksheets(w)
.Range("A:O").RemoveDuplicates Columns:=1, Header:=xlYes
End With
Next w
End With
End Sub
I wonder what the text in this message means...
I's the text you see when you 'Save As'/'CSV'.
I have a master workbook, which houses a group of 15 worksheets that house data for summary pivot tables and whatnot. Every week this master workbook gets updated with a daily report that has those 15 worksheets, but also around 20 other ones. I am just trying to get a script together to identify if they exist, and if so, to move that daily data to the master workbooks worksheet (only move data if daily wb worksheet exists in master workbook).
Here is a very general shell of what I'm trying to achieve, but I'm not well versed in determining the logic if a sheet exists, so my blnFound variable is obviously misplaced. I hope this shows a rough outline of what I'm trying to achieve. Any help is greatly appreciated!
Option Explicit
Sub Update_New_Data()
Const BasePath As String = "C:\\User\Data..."
Dim wbMaster As Workbook: Set wbMaster = ThisWorkbook
Dim wbNewData As Workbook: Set wbNewData = Workbooks.Open(BasePath & "\03.01.20.xlsx")
Dim wsMaster As Sheet
Dim blnFound As Boolean
'places all sheet names into array
With wbNewData
Dim varWsName As Variant
Dim i As Long
Dim ws As Worksheet
ReDim varWsName(1 To wbNewData.Worksheets.Count - 2)
For Each ws In wbNewData.Worksheets
Select Case ws.Name
Case "Inputs", "Data --->>>"
Case Else
i = i + 1
varWsName(i) = ws.Name
End Select
Next
End With
'if wbNewData sheet name is found in wbMaster
'then locate it and place wbNewData data into that sheet
With wbMaster
For Each wsMaster In wbMaster.Sheets
With wsMaster
If .Name = varWsName(i) Then
blnFound = True
wbNewData(Worksheets(i)).UsedRange.Copy Destination:=wbMaster(Worksheets(i)).Range("A1")
Else: blnFound = False
End If
End With
Next
End With
End Sub
To check if something exists you can use a Dictionary Object
Option Explicit
Sub Update_New_Data()
Const BasePath As String = "C:\\User\Data..."
Dim wbMaster As Workbook, wbNewData As Workbook
Set wbMaster = ThisWorkbook
Set wbNewData = Workbooks.Open(BasePath & "\03.01.20.xlsx", , False) ' read only
Dim ws As Worksheet, sKey As String, rng As Range, msg As String
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
'places all master sheet names into dictionary
For Each ws In wbMaster.Sheets
If ws.Name = "inputs" Or ws.Name = "Data --->>>" Then
' skip
Else
dict.Add CStr(ws.Name), ws.Index
Debug.Print "Added to dict", ws.Index, ws.Name
End If
Next
' if wbNewData sheet name is found in wbMaster
' then locate it and place wbNewData data into that sheet
For Each ws In wbNewData.Sheets
sKey = CStr(ws.Name)
If dict.exists(sKey) Then
' clear master
wbMaster.Sheets(dict(sKey)).cells.clear
Set rng = ws.UsedRange
rng.Copy wbMaster.Sheets(dict(sKey)).Range("A1")
msg = msg & vbCr & ws.Name
Else
Debug.Print "Not found in master", ws.Index, ws.Name
End If
Next
wbNewData.Close
' result
If Len(msg) > 0 Then
MsgBox "Sheets copied were " & msg, vbInformation
Else
MsgBox "No sheets copied", vbExclamation
End If
End Sub
Looking to use filter in workbook B, with clipboard content from workbook A. Workbook B name is a wildcard and macro needs to be run from workbook A. So far I have:
Sub SwitchAndFilter()
'
Dim wb As Workbook
For Each wb In Application.Workbooks
If wb.Name Like "*ABC_*" Then wb.Activate:
With ActiveWorkbook
'code here just getting run onto workbook A, plus don't know how to pass clipboard contents to a filter
ActiveSheet.Range("$A$1:$W$501").AutoFilter Field:=3, Criteria1:="12345" ' this should be clipboard contents from Workbook A
End With
Exit Sub
Next wb
'if code gets here, it isn't already open...
End Sub
UPDATE 1 Getting "Run-time error '9': Subscript out of range" on line:
.Sheets("Sheet1").Range("AA1").Paste
per advice below "should get the filter criteria from the range, not the clipboard" with that code I'm trying first to paste clipboard into range on wbB, and then refer to that range to filter. Full code I have now is:
Sub SwitchAndFilter3()
Dim wbA As ThisWorkbook
Dim wbB As Workbook
Set wbA = ThisWorkbook
For Each wbB In Application.Workbooks
If wbB.Name Like "*ABC_*" And wbA.Name <> wbB.Name Then
'Your with should reference the context of your for, i.e. wbB, not ActiveWorkbook.
With wbB
'You should really try to avoid Activesheet
'Also, you should get the filter criteria from the range, not the clipboard.
'
.Sheets("Sheet1").Range("AA1").Paste
.ScrollColumn = 2
'
.Sheets("Sheet1").Range("$A$1:$W$501").AutoFilter Field:=3, Criteria1:=wbB.Sheets("Sheet1").Range("AA1").Value
'If you need wbB to be active:
.Activate
End With
Exit Sub
End If
Next wbB
COPY SUB FOR #ValonMiller 9.26.18 In response to request in comment below
Sub CopyFirstOne()
Dim position As Integer
Dim substring As String
position = InStr(ActiveCell, " ")
If (position > 0) Then
substring = Left(ActiveCell, position - 1)
Dim MyText As DataObject
Set MyText = New DataObject
On Error Resume Next
MyText.setText substring
MyText.PutInClipboard
End If
'below macro works on it's own, but Calling from here crashes XL for a bit and gives error on PasteSpecial
'Call SwitchAndFilterWorks
End Sub
10.8.18 Update
Sub ListFiles_A3_Works()
Dim objFSO As Object
Dim objFolder As Object
Dim objFile As Object
Dim i As Integer
Application.Goto Reference:="Body"
Selection.ClearContents
Range("B6").Select
objFolderName = Range("A3").Value
'Create an instance of the FileSystemObject
Set objFSO = CreateObject("Scripting.FileSystemObject")
'Get the folder object
Set objFolder = objFSO.GetFolder(objFolderName)
'Set objFolder = objFSO.GetFolder(Range("A3").Value)
i = 5
'loops through each file in the directory and prints their names and path
For Each objFile In objFolder.Files
'print file name
Cells(i + 1, 1) = objFile.Name
'print file path
'Cells(i + 1, 2) = objFile.Path
i = i + 1
Next objFile
Range("B6").Select
Range("A6").Select
ActiveWindow.ScrollRow = Selection.Row
Call CopyFirstOne
End Sub
[Updated 9/26 based on discussion above]
Make sure you update the line With wbB.Sheets("Sheet1") with the correct sheet name.
Sub CopyFirstOne()
Dim position As Integer
Dim substring As String
position = InStr(ActiveCell, " ")
If (position > 0) Then
substring = Left(ActiveCell, position - 1)
Else
substring = ActiveCell.Value
End If
'Pass the filter string directly
Call SwitchAndFilter(substring)
End Sub
Sub SwitchAndFilter(fitlerValue As String)
Dim wb As Workbook
For Each wb In Application.Workbooks
If wb.Name Like "*ABC_*" And ThisWorkbook.Name <> wb.Name Then
'Changed with to target Sheet, instead of Workbook
With wb.Sheets("Sheet1")
.Range("$A$1:$W$501").AutoFilter Field:=3, Criteria1:=fitlerValue
'Optional
.Activate
End With
Exit Sub
End If
Next wb
'if code gets here, it isn't already open...
End Sub
I don't think this is the best solution, but to address what I believe to be the root cause of your copy/paste issue, try this:
Sub CopyFirstOne()
Dim position As Integer
Dim substring As String
Dim MyText As DataObject
Set MyText = New DataObject
position = InStr(ActiveCell, " ")
If (position > 0) Then
substring = Left(ActiveCell, position - 1)
Else
substring = ActiveCell.Value
End If
On Error Resume Next
MyText.setText substring
MyText.PutInClipboard
Call SwitchAndFilterWorks
End Sub
I keep getting a 'Method 'SaveAS' of object '_Workbook' failed, I can't for the life of me figure out why. Code below... any recommendation unrelated to the initial question are welcome!
Private Sub CommandButton1_Click()
'Declarations
'The two workbooks to be involved
Dim SourceWB As Workbook
Dim DestinationWB As Workbook
'values to contain cell data to be copied across the worksheet
Dim systemName As Variant
Dim systemID As Variant
'Counter variable to allow for the loop
Dim counter As Integer
'Set the source workbook equal to the current workbook
Set SourceWB = ActiveWorkbook
For counter = 1 To 5
'Set the values for the two data values to be copied
systemName = SourceWB.Sheets("Sheet1").Cells(counter, 1).Value
systemID = SourceWB.Sheets("Sheet1").Cells(counter, 2).Value
'Open the destination Workbook
Set DestinationWB = Workbooks.Open("Path to workbook")
'Set destination cells equal to the copied data from the source sheet
DestinationWB.Sheets("Questionnaire").Cells(7, 3).Value = systemName
DestinationWB.Sheets("Questionnaire").Cells(8, 3).Value = systemID
'Set fname to save Destination Workbook
Fname = "H:\Desktop\Automated Questionnaires to send\" & systemName & " Applicability Questionnaire.xlsm"
'Save the Destination workbook
DestinationWB.SaveAs Filename:=Fname, FileFormat:=52
DestinationWB.Close
Next counter
End Sub