I have a main workbook and a sub workbook that macro commands to open
1) Main workbook = Database
Worksheet in Main Workbook = Customer database
Sub workbook = Orders
These two books are open for macro to run.
1) I need to import data Range C:F from Orders to Customer Database B:E if Cell B from Orders contains New Member
2) The worksheet in database already contains data. Hence, I want it to add on to the existing sheet in Database
Please help.
Dim wsSource As Worksheet
Dim wbSource As Workbook
Dim wsTarget As Worksheet
Dim wbTarget As Workbook
Dim findRange As Range
Dim lastline As Integer
Dim file As String
file = "Orders.xlsx"
Set wbSource = ThisWorkbook
Set wsSource = wbSource.Sheets(1)
Set wbTarget = Workbooks.Open(file)
Set wsTarget = wbTarget.Sheets(1)
wsTarget.Activate
Set findRange = wsTarget.Range("C2:F389")
findRange.Replace What:="xxx-string",Replacement:=wsSource.Range("b2:e2").Value, LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False
lastline = wbSource.Sheets(1).Range("X65536").End(xlUp).Row
Dim d As Integer
Dim j As Integer
d = 3
j = 2
For b = 1 To lastline
If wsTarget.Range("B" & j) = "New Member" Then
d = d + 1
wsSource.Range("B" & j).Value = wsTarget.Range("C" & d).Value
wsSource.Range("C" & j).Value = wsTarget.Range("D" & d).Value
wsSource.Range("D" & j).Value = wsTarget.Range("E" & d).Value
wsSource.Range("E" & j).Value = wsTarget.Range("F" & d).Value
End If
j = j + 1
Next b
This answer is based on items 1 and 2 you enumerated above.
I'm not sure what you want to accomplish with the .Replace method so I remove it.
Sub Consolidate()
Dim wsSource As Worksheet
Dim wbSource As Workbook
Dim wsTarget As Worksheet
Dim wbTarget As Workbook
Dim findRange As Range
Dim lastline As Integer
Dim file As Variant '~~> declared as Variant
Set wbSource = Thisworkbook
Set wsSource = wbSource.Sheets(1) '~~>use index only if you have 1 sheet only
file = Application.GetOpenFilename("Excel Files, *.xlsx") '~~> allows you to select the file to load
If file <> False Then
Set wbTarget = Workbooks.Open(file)
Set wsTarget = wbTarget.Sheets(1)
With wsTarget
lastline = .Range("B" & .Rows.Count).End(xlUp).Row
Set findRange = .Range("B1:F" & lastline)
With findRange
.Autofilter 1, "New Member"
.Offset(1,1).Resize(.Rows.Count-1, .Columns.Count-1).SpecialCells(xlCellTypeVisible).Copy _
wsSource.Range("B" & wsSource.Rows.Count).End(xlUp).Offset(1,0)
End With
End With
Else
MsgBox "No file selected. Exiting now." : Exit Sub
End If
wbTarget.Close False
wbSource.Save
End Sub
No need to loop through the whole range.
I used .AutoFilter method instead.
Hope this is close to what you want.
Related
Expected situation: I have a loop which is checking all sheets of a workbook for certain keywords, copy/pasting them according to certain conditions and ist creating a new workbook for every sheet with the said values.
Example:
Source Workbook with Sheet1,Sheet2 and Sheet3 --->
New_Workbook_1(with values of Sheet1), New_Workbook_2(with values of
Sheet2), New_Workbook_3(with values of Sheet3)
Actual situation: only the values of the last sheet of the workbook are pasted into the newly created workbooks...I can't tell why? .
Example:
Source Workbook with Sheet1,Sheet2 and Sheet3 ---> New_Workbook_1(with
values of Sheet3), New_Workbook_2(with values of Sheet3),
New_Workbook_3(with values of Sheet3)
Public Sub TransferFile(TemplateFile As String, SourceFile As String)
Dim wbSource As Workbook
Set wbSource = Workbooks.Open(SourceFile) 'open source
Dim rFnd As Range
Dim r1st As Range
Dim ws As Worksheet
Dim arr(1 To 4) As Variant
Dim i As Long
Dim wbTemplate As Workbook
Dim NewWbName As String
Dim wsSource As Worksheet
For Each wsSource In wbSource.Worksheets 'loop through all worksheets in source workbook
Set wbTemplate = Workbooks.Open(TemplateFile) 'open new template
'/* Definition of the value range */
arr(1) = "XX"
arr(2) = "Data 2"
arr(3) = "Test 3"
arr(4) = "XP35"
For i = LBound(arr) To UBound(arr)
For Each ws In wbSource.Worksheets
Debug.Print ws.Name
Set rFnd = ws.UsedRange.Find(what:=arr(i), LookIn:=xlValues, lookat:=xlPart, SearchOrder:=xlRows, _
SearchDirection:=xlNext, MatchCase:=False)
If Not rFnd Is Nothing Then
Set r1st = rFnd
Do
If i = 1 Then
wbTemplate.Sheets("Header").Range("A3").Value = "XX"
ElseIf i = 2 Then
wbTemplate.Sheets("Header").Range("B9").Value = rFnd.Offset(0, 1).Value
ElseIf i = 3 Then
wbTemplate.Sheets("Header").Range("D7").Value = rFnd.Offset(0, 2).Value
ElseIf i = 4 Then
wbTemplate.Sheets("MM1").Range("A8").Value = "2"
End If
Set rFnd = ws.UsedRange.FindNext(rFnd)
Loop Until r1st.Address = rFnd.Address
End If
Next
Next
NewWbName = Left(wbSource.Name, InStr(wbSource.Name, ".") - 1)
For i = 1 To 9
'check for existence of proposed filename
If Len(Dir(wbSource.Path & Application.PathSeparator & NewWbName & "_V" & i & ".xlsx")) = 0 Then
wbTemplate.SaveAs wbSource.Path & Application.PathSeparator & NewWbName & "_V" & i & ".xlsx"
Exit For
End If
Next i
wbTemplate.Close False 'close template
Next wsSource
wbSource.Close False 'close source
End Sub
Place a breakpoit on line ( by pressing F9 in that line) and run the program. When vba stopped at that line, before pressing F5 to continue, go to your folder and open newly created workbook and see is it true or not. continue and share the results to find out where is the issue.
I've a strange problem.
the following code will run using F8 or pressing the run button on the development module.
But when added to the excel ribbon as a macro by the following process the vlookup will return #N/A :
1.right click on the excel toolbar > customize the ribbon
choose macro commands
add it to a new group.
the code is :
Sub Compare()
'set primary Workbook
'find last cell'
Dim WS As Worksheet
Dim LastCell As Range
Dim LastCellRowNumber As Long
Set WS = Worksheets("Sheet1")
With WS
Set LastCell = .Cells(.Rows.Count, "A").End(xlUp)
LastCellRowNumber = LastCell.Row
'MsgBox (LastCell.Row)
End With
'Adding Index Column
Columns("A:A").Select
Selection.Insert Shift:=xlToRight
[A2].Formula = "=G2&H2"
Range("A2:A" & LastCellRowNumber).FillDown
'adding headers
[Ag1].Value = "Resale"
[Ah1].Value = "Cost"
[Ai1].Value = "disti"
'set primary Workbook
Dim Pri As Workbook
Set Pri = ActiveWorkbook
'open company quotes
Workbooks.Open ("R:\company\DATA\company quotes.xlsx")
'find last cell'
Dim WSq As Worksheet
Dim LastCellq As Range
Dim LastCellRowNumberq As Long
Set WSq = Worksheets("Quote Summary")
With WSq
Set LastCellq = .Cells(.Rows.Count, "A").End(xlUp)
LastCellRowNumberq = LastCellq.Row
'MsgBox (LastCell.Row)
End With
Columns("A:A").Select
Selection.Insert Shift:=xlToRight
Dim quotes As Workbook
Set quotes = ActiveWorkbook
[A2].Formula = "=J2&B2"
Range("A2:A" & LastCellRowNumberq).FillDown
Pri.Activate
Dim i As Integer
For i = 2 To LastCellRowNumber
Dim result As String
Dim sheet As Worksheet
Range("AG" & i) = Application.VLookup(Sheet1.Range("A" & i), Workbooks("company quotes.xlsx").Worksheets("Quote Summary").Range("A2:AS" & LastCellRowNumberq), 17, False)
Range("AH" & i) = Application.VLookup(Sheet1.Range("A" & i), Workbooks("company quotes.xlsx").Worksheets("Quote Summary").Range("A2:AS" & LastCellRowNumberq), 19, False)
Range("Ai" & i) = Application.VLookup(Sheet1.Range("A" & i), Workbooks("company quotes.xlsx").Worksheets("Quote Summary").Range("A2:AS" & LastCellRowNumberq), 20, False)
Next i
End Sub
I've tried to fix any referencing issues I could find but you'll need to have a look through and make sure all of the Range references are prefixed with the correct Workbook and Worksheet as it wasn't too clear which worksheet they were coming from in the original code:
Sub Compare()
'Set primary Workbook
'Find last cell
Dim WS As Worksheet
Dim LastCellRowNumber As Long
Set WS = ThisWorkbook.Sheets("Sheet1")
LastCellRowNumber = WS.Cells(WS.Rows.Count, "A").End(xlUp).Row
'MsgBox (LastCell.Row)
'Adding Index Column
WS.Columns("A:A").Insert Shift:=xlToRight
WS.Range("A2:A" & LastCellRowNumber).Formula = "=G2&H2"
'adding headers
WS.Range("AG1").Value = "Resale"
WS.Range("AH1").Value = "Cost"
WS.Range("AI1").Value = "disti"
'open company quotes
Dim wbCompQuotes As Workbook
Set wbCompQuotes = Workbooks.Open ("R:\company\DATA\company quotes.xlsx")
'find last cell'
Dim wsQuoteSum As Worksheet
Dim LastCellRowNumberq As Long
Set wsQuoteSum = wbCompQuotes.Worksheets("Quote Summary")
LastCellRowNumberq = wsQuoteSum.Cells(wsQuoteSum.Rows.Count, "A").End(xlUp).Row
'MsgBox (LastCell.Row)
wsQuoteSum.Columns("A:A").Insert Shift:=xlToRight
wsQuoteSum.Range("A2:A" & LastCellRowNumberq).Formula = "=J2&B2"
Dim i As Long
For i = 2 To LastCellRowNumber
WS.Range("AG" & i) = Application.VLookup(WS.Range("A" & i), wsQuoteSum.Range("A2:AS" & LastCellRowNumberq), 17, False)
WS.Range("AH" & i) = Application.VLookup(WS.Range("A" & i), wsQuoteSum.Range("A2:AS" & LastCellRowNumberq), 19, False)
WS.Range("AI" & i) = Application.VLookup(WS.Range("A" & i), wsQuoteSum.Range("A2:AS" & LastCellRowNumberq), 20, False)
Next i
End Sub
I am new to VBA and If anyone can help, I'd greatly appreciate it. I just need help in simple VBA loop in following code.
I am trying to loop through excel files in a folder and copy specific data from source Worksheet in all files to a new workbook (sheet 2). I have a code which does 70% of the job but I am having difficulty in picking some data and copying it in specific format.
Option Explicit
Const FOLDER_PATH = "C:\Temp\" 'REMEMBER END BACKSLASH
Sub ImportWorksheets()
'=============================================
'Process all Excel files in specified folder
'=============================================
Dim sFile As String 'file to process
Dim wsTarget As Worksheet
Dim wbSource As Workbook
Dim wsSource As Worksheet
Dim rowTarget As Long 'output row
Dim FirstRow As Long, LastRow As Long
FirstRow = 1
LastRow = 5
Dim RowRange As Range
rowTarget = 2
'check the folder exists
If Not FileFolderExists(FOLDER_PATH) Then
MsgBox "Specified folder does not exist, exiting!"
Exit Sub
End If
'reset application settings in event of error
On Error Goto errHandler
Application.ScreenUpdating = False
'set up the target worksheet
Set wsTarget = Sheets("Sheet2")
'loop through the Excel files in the folder
sFile = Dir(FOLDER_PATH & "*.xls*")
Do Until sFile = ""
'open the source file and set the source worksheet - ASSUMED WORKSHEET(1)
Set wbSource = Workbooks.Open(FOLDER_PATH & sFile)
Set wsSource = Sheets("DispForm") 'EDIT IF NECESSARY
'import the data
With wsTarget
For Each rw In RowRange
If wsSource.Cells(rw.Row, 1) & wsSource.Cells(rw.Row + 1, 1) = "" Then
Exit For
End If
.Range("A" & rowTarget).Value = wsSource.Range("B1").Value
.Range("B" & rowTarget).Value = wsSource.Cells(rw.Row, 2)
.Range("C" & rowTarget).Value = wsSource.Cells(rw.Row, 4)
.Range("D" & rowTarget).Value = sFile
rowTarget = rowTarget + 1
Next rw
End With
'close the source workbook, increment the output row and get the next file
wbSource.Close SaveChanges:=False
rowTarget = rowTarget + 1
sFile = Dir()
Loop
errHandler:
On Error Resume Next
Application.ScreenUpdating = True
'tidy up
Set wsSource = Nothing
Set wbSource = Nothing
Set wsTarget = Nothing
End Sub
Private Function FileFolderExists(strPath As String) As Boolean
If Not Dir(strPath, vbDirectory) = vbNullString Then FileFolderExists = True
End Function
you only copy one row of data from your source file. so you need either to have a loop inside your file loop to loop all the rows, or to have a range to select all the rows.
try something like the following:
Dim FirstRow As Long, LastRow As Long
FirstRow = 9
LastRow = 100
Set rowRange = wsSource.Range("A" & FirstRow & ":A" & LastRow)
With wsTarget
For Each rw In rowRange
If wsSource.Cells(rw.Row, 2) = "" Then
Exit For
End If
.Range("A" & rowTarget).Value = wsSource.Cells(rw.Row, 2)
.Range("B" & rowTarget).Value = wsSource.Cells(rw.Row, 3)
Next rw
End With
I am trying to use VBA in Excel to separate rows into separate sheets and retain headers. Below is what I have so far. It works except I get the header row, then the individual row I want to move to the sheet is there BUT it's there three times instead of one. I am basically going by trial and error and I am stumped. Help please! I have no experience with this:
Sub DispatchTimeSeriesToSheets()
Dim ws As Worksheet
Set ws = Sheets("Scoring")
Dim LastRow As Long
LastRow = Range("A" & ws.Rows.Count).End(xlUp).Row
' stop processing if we don't have any data
If LastRow < 2 Then Exit Sub
Application.ScreenUpdating = False
SortScoring LastRow, ws
CopyDataToSheets LastRow, ws
ws.Select
Application.ScreenUpdating = True
End Sub
Sub SortScoring(LastRow As Long, ws As Worksheet)
ws.Range("A4:W" & LastRow).Sort Key1:=ws.Range("A4"), Key2:=ws.Range("W4")
End Sub
Sub CopyDataToSheets(LastRow As Long, src As Worksheet)
Dim rng As Range
Dim cell As Range
Dim Series As String
Dim SeriesStart As Long
Dim SeriesLast As Long
Set rng = Range("A4:A" & LastRow)
SeriesStart = 2
Series = Range("A" & SeriesStart).Value
For Each cell In rng
If cell.Value <> Series Then
SeriesLast = cell.Row - 1
CopySeriesToNewSheet src, SeriesStart, SeriesLast, Series
Series = cell.Value
SeriesStart = cell.Row
End If
Next
' copy the last series
SeriesLast = LastRow
CopySeriesToNewSheet src, SeriesStart, SeriesLast, Series
End Sub
Sub CopySeriesToNewSheet(src As Worksheet, Start As Long, Last As Long, _
name As String)
Dim tgt As Worksheet
If (SheetExists(name)) Then
MsgBox "Sheet " & name & " already exists. " _
& "Please delete or move existing sheets before" _
& " copying data from the Scoring.", vbCritical, _
"Time Series Parser"
End
End If
Worksheets.Add(After:=Worksheets(Worksheets.Count)).name = name
Set tgt = Sheets(name)
' copy header row from src to tgt
tgt.Range("A1:W1").Value = src.Range("A1:W1").Value
' copy data from src to tgt
tgt.Range("A4:W" & Last - Start + 2).Value = _
src.Range("A" & Start & ":W" & Last).Value
End Sub
Function SheetExists(name As String) As Boolean
Dim ws As Worksheet
SheetExists = True
On Error Resume Next
Set ws = Sheets(name)
If ws Is Nothing Then
SheetExists = False
End If
End Function
Try this:
Sub doitall()
Dim ows As Worksheet
Dim tws As Worksheet
Dim rng As Range
Dim cel As Range
Dim LastRow As Long
Dim tLastRow As Long
Set ows = Sheets("Scoring")
With ows
LastRow = .Range("A" & .Rows.Count).End(xlUp).Row
Set rng = .Range("A4:A" & LastRow)
For Each cel In rng
If Not SheetExists(cel.Value) Then
Set tws = Worksheets.Add(After:=Sheets(Worksheets.Count))
tws.Name = cel.Value
tws.Rows(1).Resize(3).Value = .Rows(1).Resize(3).Value
Else
Set tws = Sheets(cel.Value)
End If
tLastRow = tws.Range("A" & tws.Rows.Count).End(xlUp).Offset(1).Row
tws.Rows(tLastRow).Value = .Rows(cel.Row).Value
Next
End With
End Sub
Function SheetExists(SName As String, _
Optional ByVal WB As Workbook) As Boolean
On Error Resume Next
If WB Is Nothing Then Set WB = ActiveWorkbook
SheetExists = CBool(Len(WB.Sheets(SName).Name))
End Function
This will do what you are looking for
Const HeaderRow = 3
Sub MoveRecordsByValues()
Dim ws As Worksheet
Dim dws As Worksheet
Dim SheetName As String
Application.DisplayAlerts = False
For Each ws In Sheets
If ws.name <> "Scoring" Then ws.Delete
Next ws
Set ws = Sheets("Scoring")
StartRow = HeaderRow + 1
LastRow = ws.Range("A" & ws.Rows.Count).End(xlUp).Row
For RowCounter = StartRow To LastRow
SheetName = ws.Cells(RowCounter, 1)
If Not SheetExists(SheetName) Then SetUpSheet SheetName, ws, HeaderRow
Set dws = Worksheets(SheetName)
DestLastRow = dws.Range("A" & dws.Rows.Count).End(xlUp).Row + 1
ws.Rows(RowCounter).Copy dws.Cells(DestLastRow, 1)
Next RowCounter
Application.DisplayAlerts = True
End Sub
Function SheetExists(name As String) As Boolean
SheetExists = True
On Error GoTo errorhandler
Sheets(name).Activate
Exit Function
errorhandler:
SheetExists = False
End Function
Sub SetUpSheet(name, SourceSheet, HeaderRow)
Dim DestSheet As Worksheet
Set DestSheet = Sheets.Add
DestSheet.name = name
SourceSheet.Rows(1).Copy DestSheet.Cells(1, 1)
SourceSheet.Rows(2).Copy DestSheet.Cells(2, 1)
SourceSheet.Rows(3).Copy DestSheet.Cells(3, 1)
End Sub
I was able to compile the sheets in one sheet however I would like to indicate the sheets I want to copy. The source file may have multiple sheets name Delta Prices # therefore I would like to end the loop once it cannot find the sheet's name. Code is:
Option Explicit
Sub CreateDeltaReport()
Dim Newbook As Window
Dim wb As Workbook
Dim wb2 As Workbook
Dim ws As Worksheet
Dim vFile As Variant
Dim wkb As Workbook
Dim wb3 As Workbook
Dim s As Worksheets
Set wb = ThisWorkbook
vFile = Application.GetOpenFilename("All-Files,*.xl**", 1, "Select One File To Open", , False)
If TypeName(vFile) = "Boolean" Then Exit Sub
Workbooks.Open vFile
Set wb2 = ActiveWorkbook
wb2.Activate
Dim j As Integer
Dim h As Integer
On Error Resume Next
Sheets.Add After:=Sheets(Sheets.Count)
ActiveSheet.Name = "Raw Delta"
Sheets("Delta Prices 1").Activate
Range("A1").EntireRow.Select
Selection.Copy Destination:=Sheets("Raw Delta").Range("A1")
h = 1
For Each s In ActiveWorkbook.Sheets
If s.Name <> "Raw Delta" Then
Do
Application.GoTo Sheets("Delta Prices " & h).[a1] ' Sheet name is Delta Prices 1
Selection.CurrentRegion.Select
Selection.Offset(1, 0).Resize(Selection.Rows.Count - 1).Select
Selection.Copy Destination:=Sheets("Raw Delta").Cells(Rows.Count, 1).End(xlUp)(2)
h = h + 1 ' add 1 to h so the sheet name will be "Delta Prices 2 a"
Loop Until s.Name <> ("Delta Prices " & h) ' loop until Sheet name is not "Delta Prices #"
End If
Next
End Sub
Something like this (untested):
Sub CreateDeltaReport()
Dim wb2 As Workbook
Dim vFile As Variant
Dim wkb As Workbook
Dim s As Worksheet
Dim rd As Worksheet, rng As Range
Dim h As Integer
vFile = Application.GetOpenFilename("All-Files,*.xl**", 1, _
"Select One File To Open", , False)
If vFile = False Then Exit Sub
Set wb2 = Workbooks.Open(vFile)
Set rd = wb2.Sheets.Add(After:=wb2.Sheets(wb2.Sheets.Count))
rd.Name = "Raw Delta"
h = 1
Do
Set s = Nothing
On Error Resume Next
Set s = wb2.Worksheets("Delta Prices " & h)
On Error GoTo 0
If s Is Nothing Then
Exit Do
Else
With s.Range("A1").CurrentRegion
.Offset(1, 0).Resize(.Rows.Count - 1, .Columns.Count).Copy _
rd.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0)
End With
End If
h = h + 1
Loop
End Sub