I have a partial solution for a former question I asked, I hope it's okay to open a new question.
What I have:
.csv-file 1
00|G1|G2|
K4|__|X_|
K5|X_|X_|
.csv-file 2
00|G3|G7|G9|G12
K6|X_|__|X_|__|
K7|__|X_|X_|__|
K8|__|__|__|X_|
What I want:
final .csv (or .xls) file
00|G1|G2|G3|G7|G9|G12
K4|__|X_|__|__|__|__|
K5|X_|X_|__|__|__|__|
K6|__|__|X_|__|X_|__|
K7|__|__|__|X_|X_|__|
K8|__|__|__|__|__|X_|
So the top row of file 2 -- shall be added to the right -- of the top row of file 1.
The first column to the left of file 2 -- shall be added underneath -- the first column of file 1.
The corresponding Xes shall then be just copy and pasted -- to the down right corner -- of the Xes of file 1.
I have a lot of .csv-files and no idea how to use VBA.
I'd very much appreciate your help!
Regards,
Tom
Try this it's a bit convoluted but I think this is what you want. I've put it so they are in the same workbook but that is easily changed to opening the files with setting a workbook with Workbooks.Open()
Edit to show how I do to an open csv. (there are many ways you can do all the below)
Sub simplePaste()
Dim lastRow0 As Long
Dim lastColumn0 As Long
Dim lastColumn1
Dim ws0 As Worksheet
Dim ws1 As Worksheet
Dim wb1 As Workbook
Dim CopyRange As Range
Dim pasteRange As Range
Set ws0 = ThisWorkbook.Sheets("Sheet1")
Set wb1 = Workbooks.Open("C:\Users\james\Desktop\source.csv")
Set ws1 = wb1.Sheets(1)
lastRow0 = ws1.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
lastColumn0 = ws1.Cells.Find(What:="*", SearchDirection:=xlPrevious, SearchOrder:=xlByColumns).Column
lastColumn1 = ws0.Cells.Find(What:="*", SearchDirection:=xlPrevious, SearchOrder:=xlByColumns).Column
Set CopyRange = ws1.Range(ws1.Cells(1, 1), ws1.Cells(lastRow0, lastColumn0))
Set pasteRange = ws0.Cells(1, lastColumn1 + 1)
CopyRange.Copy
pasteRange.PasteSpecial
wb1.Close
End Sub
So this code should do the trick, it only misses some kind of function to crawl through your directory and open the files one by one. But that doesnt seem to hard to write.
Sub simplePaste()
Dim lastRow0 As Long
Dim lastColumn0 As Long
Dim lastColumn1
Dim ws0 As Worksheet
Dim ws1 As Worksheet
Dim CopyRange As Range
Dim pasteRange As Range
Set ws0 = ThisWorkbook.Sheets("Sheet1")
Set ws1 = ThisWorkbook.Sheets("Sheet2")
lastRow0 = ws0.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
lastColumn0 = ws0.Cells.Find(What:="*", SearchDirection:=xlPrevious, SearchOrder:=xlByColumns).Column
lastRow1 = ws1.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
vlastColumn1 = ws1.Cells.Find(What:="*", SearchDirection:=xlPrevious, SearchOrder:=xlByColumns).Column
Set CopyRange = ws1.Range(ws1.Cells(1, 2), ws1.Cells(1, lastColumn1))
Set pasteRange = ws0.Cells(1, lastColumn0 + 1)
CopyRange.Copy
pasteRange.PasteSpecial
Set CopyRange = ws1.Range(ws1.Cells(2, 1), ws1.Cells(lastRow1, 1))
Set pasteRange = ws0.Cells(lastRow0 + 1, 1)
CopyRange.Copy
pasteRange.PasteSpecial
Set CopyRange = ws1.Range(ws1.Cells(2, 2), ws1.Cells(lastRow1 - 1, lastColumn1))
Set pasteRange = ws0.Cells(lastRow0 + 1, lastColumn0 + 1)
CopyRange.Copy
pasteRange.PasteSpecial
End Sub
What it does:
get the count of rows and columns in each sheet
set the copy range for the first row in sheet 2
set the paste cell in sheet 1 (first cell with no content in row 1)
paste
set the copy range to the first column in sheet 2
set the paste cell in sheet 1 (first cell with no content in column 1)
paste
set the copy range in sheet 2 from B2 to the cell with the coordinates (lastColumn|lastRow) ((That's where all the Xes are)
set the paste cell in sheet 1. This is the cell after the block of Xes in Sheet 1
paste
Job is done!
Thanks for your help!
Tom
Related
Got a bunch of worksheets in the same workbook that have a specific range of interest that starts with finding string 'Green'. Let's call this Range (A) that I'm interested in copying and pasting into a master sheet to form a database in same workbook. I found some useful code and got this part to work gr8!
There is a date value in each worksheet in cell(3,3). What's missing is adding this date value from each worksheet and past it to column B in the master sheet 'Main' such that the date value extends to match the length of the pasted Range (A).
all help is appreciated
Sub FindRangeHistory()
'// in MainDB workbook for each trade sheet, copy and paste specific range into 'Main' sheet
Dim fnd As String, faddr As String
Dim rng As Range, foundCell As Range
Dim ws As Worksheet
Dim ws_count As Integer, i As Integer
ws_count = ThisWorkbook.Worksheets.Count
For i = 1 To ws_count
With ThisWorkbook
'initialize main sheet and keyword search
Set ws = .Worksheets("Main")
fnd = "New Life"
'Search for keyword in sheet
With .Worksheets(i)
Set foundCell = .Cells.Find(What:=fnd, after:=.Cells.SpecialCells(xlCellTypeLastCell), _
LookIn:=xlFormulas, LookAt:=xlWhole, _
SearchOrder:=xlByRows, SearchDirection:=xlNext)
'Test to see if anything was found
If Not foundCell Is Nothing Then
faddr = foundCell.Address
Set rng = .Range(foundCell, foundCell.End(xlDown))
Do
Set rng = Union(rng, .Range(foundCell, foundCell.End(xlDown)).Resize(, 7))
Set foundCell = .Cells.FindNext(after:=foundCell)
Loop Until foundCell.Address = faddr
Set rng = rng.Offset(1, 0)
rng.Copy
ws.Cells(Rows.Count, "C").End(xlUp).PasteSpecial Paste:=xlPasteValues
Worksheets(i).Cells(3, 3).Copy
ws.Cells(Rows.Count, "B").End(xlUp).PasteSpecial Paste:=xlPasteValuesAndNumberFormats
End If
End With
End With
Next i
End Sub
You could do it like this:
'...
'...
Dim nextRowC As Long, lastRowC As Long
nextRowC = ws.Cells(Rows.Count, "C").End(xlUp).Row + 1 'first empty row in ColC before paste
rng.Copy
ws.Cells(nextRowC, "C").PasteSpecial Paste:=xlPasteValues
lastRowC = ws.Cells(Rows.Count, "C").End(xlUp).Row 'last used row in ColC after paste
.Worksheets(i).Cells(3, 3).Copy
ws.Range(ws.Cells(nextRowC, "B"), ws.Cells(lastRowC, "B")). _
PasteSpecial Paste:=xlPasteValuesAndNumberFormats
'...
'...
What I am trying to accomplish:
Find cell corresponding value from sheet 1
Loop through a list of items up to the last one starting from one cell below the searched value
Copy the list to sheet 2
Here is my list of items:
BOMS
So what I am searching for is "BOMn" and trying to copy the list below to another sheet inside range A2:B10 (1st row is headers). Here is my code:
Sub copy_bom()
Dim wb As Workbook
Dim ws_boms As Worksheet
Dim ws_project As Worksheet
Set wb = ThisWorkbook
Set ws_boms = wb.Sheets("Sheet1")
Set ws_project = wb.Sheets("Sheet2")
Dim rng As Range
Dim cellFind As Range
Dim lastRow As Long
Set rng = ws_boms.Range("A1:A50")
With rng
Set cellFind = .Find(What:="BOM2", LookAt:=xlWhole, MatchCase:=False, SearchFormat:=False)
If Not cellFind Is Nothing Then
For lastRow = cellFind.Row + 1 To Range("A" & Rows.Count).End(xlUp).Row
ws_project.Range("A10").End(xlUp).Offset(1, 0).Value = .Cells(lastRow, 1).Value
ws_project.Range("A10").End(xlUp).Offset(0, 1).Value = .Cells(lastRow, 2).Value
Next
End If
End With
End Sub
My problem is that the list "scrambles" and in the target sheet the order is completely wrong and some of the items are missing. Is there a clear reason for that behavior or a better way to accomplish what I am trying to do? Any help is appreciated!
I have some code in which I am trying to sort the data set in a csv file based on the content of a cell in another (the main) workbook. Then based on this sort, copy a range of visible cells between the first and sixth columns, but with a dynamic last row thus the range will be dynamic. This dynamic range is then pasted into the main sheet, which will then allow me to do further work on this dataset.
Can't seem to get the sort to work or the dynamic range working. I've tried all sorts of variation on the code below and am looking for some inspiration.
Sub Get_OA_Data()
'Find OA data from source SQL file and copy into serial number generator
Dim ws As Worksheet
Dim wkb2 As Workbook
Dim ws2 As Worksheet
Dim rng As Range
Dim rng2 As Range
Dim LastRow As Long
Dim LastColumn As Long
Dim StartCell As Range
'This section sets the workbooks and worksheets to be used for this macro
Set ws = ThisWorkbook.Worksheets("Data Entry")
Set wkb2 = Workbooks.Open("\\srvabdotfpr08\PC_APPS\forum\Gateshead Serialisation\sys_serialisation1.csv")
Set ws2 = wkb2.Worksheets("sys_serialisation1")
Set rng2 = ws.Range("F6")
' This line deletes any content of the cannot assign serial number added previously
ws.Range("I6:I7").ClearContents
'This hides all rows which do not match the desired OA number (found in rng2)
For Each Cell In ws2.Range("A1").End(xlDown)
If Left(Cell.Value, 6) <> rng2.Value Then
Cell.EntireRow.Hidden = True
End If
Next Cell
Set StartCell = ws2.Range("A1")
LastRow = StartCell.SpecialCells(xlCellTypeVisible).Row
LastColumn = StartCell.SpecialCells(xlCellTypeVisible).Column
'This section selects and copies the visible range from csv file into serialisation generator
Set rng = ws2.Range(StartCell.ws2.Cells(LastRow, LastColumn))
rng.Copy
ws.Activate
ws.Range("D12").Select
Selection.PasteSpecial 'Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End Sub
Any help would be greatly appreciated, I've bought a couple of books, but none of the stuff in my books is helping with this issue.
P.S I have used very similar code with specific set ranges and it works fine, but this one has me stumped. There may also be an issue with the dataset- which is why I have the LEFT formula in the code (but this seems to work OK).
Try...
Option Explicit
Sub Get_OA_Data()
Dim wkb2 As Workbook
Dim ws As Worksheet, ws2 As Worksheet
Dim rng As Range, xCell As Range
Dim LR As Long, LC As Long, LR2 As Long
Set ws = ThisWorkbook.Worksheets("Data Entry")
Set wkb2 = Workbooks.Open("\\srvabdotfpr08\PC_APPS\forum\Gateshead Serialisation\sys_serialisation1.csv")
Set ws2 = wkb2.Worksheets("sys_serialisation1")
ws.Range("I6:I7").ClearContents
LR2 = ws2.Range("A" & ws.Rows.Count).End(xlUp).Row
For Each xCell In ws2.Range("A1:A" & LR2)
xCell.EntireRow.Hidden = Left(xCell.Value, 6) <> ws.Range("F6")
Next xCell
LR = ws2.Range("A" & ws.Rows.Count).End(xlUp).Row
LC = ws2.Cells(1, ws.Columns.Count).End(xlToLeft).Column
Set rng = ws2.Range(ws2.Cells(1, 1), ws2.Cells(LR, LC))
rng.SpecialCells(xlCellTypeVisible).Copy
ws2.Range("D12").PasteSpecial xlPasteValues
End Sub
I have 2 worksheets. sheet1 is monthly Value on col A. Sheet 2 is daily value on col A, I would Like Excel to look for the same value in worksheet 2 (Daily), then once it finds that exact value, to copy the matched rows form sheet 1 (monthly) and paste it in sheet 2 (Daily).
Any ideas how to write a VBA code that will automate this copy and paste values process? (see the screenshot)
[1]: https://i.stack.imgur.com/G5LqW.png
[on the right handside, data is per month (last day of each month), i need to match col Aof both sheets, and bring the data to other sheet on exact day (last day of that month)][1]
Untested
Sub Copy18()
Dim wb As Workbook
Dim wsD2 As worksheet, wsM2 As Worksheets
Dim LastRow As long, LastCol As Long, i as long
Dim Cell As Range, Rng As Range, SearchR As Range, CopyRng As Range, PasteRng As Range
Set wb = ThisWorkbook
Set wsD2 = wb.Sheets("Daily-2")
Set wsM2 = wb.Sheets("Monhly-2")
LastCol = wsM2.Cells(1, Columns.Count).End(xlToLeft).Column
LastRow = wsM2.Cells(Rows.Count, 1).End(xlUp).Row
Set Rng = wsD2.Range(wsD2.Cells(1,1), wsD2.Cells(LastRow, LastCol))
For Each Cell in Rng
Set SearchR = wsM2.Range("A:A").Find(Cell.Value, LookAt:=xlWhole)
If Not SearchR Is Nothing Then
i = LastCol = wsM2.Cells(SearchR.Row, Columns.Count).End(xlToLeft).Column
Set CopyRng = wsM2.Range(wsM2.Cells(SearchR.Row, 1), wsM2.Cells(SearchR.Row, i))
Set PasteRng = wsD2.Range(wsD2.Cells(LastRow + 1, 1), wsD2.Cells(LastRow + 1, i))
PasteRng.Value = CopyRng.Value
LastRow = LastRow + 1
End If
Next Cell
End Sub
I'm very new to writing Macros in Excel, and have done a bit of looking around to try and solve my problem, but I haven't found a solution yet that works.
I'm trying to write a Macro to do the following:
I'm trying to copy data from Sheet 1, Workbook 1 based on column headings (so for example, I want to copy all the data under the column name "Sort"). The number of rows of data in this row may increase/decrease. I then want to paste this data into Sheet 2, Workbook 2 under the column name "Name". Columns may be added/removed from both workbooks, which is why I want to write the macro to copy based on the column name rather than a column number.
I have been using the below code, which I've tried putting together based on similar but slightly different requests I've found online, but when I run the macro, nothing much happens - I've written the Macro in Workbook 2 and it just opens Workbook 1.
If anyone can see something wrong with my code or suggest an alternative, I'd be extremely grateful for any help. Thanks!!!
Sub CopyProjectName()
Dim CurrentWS As Worksheet
Set CurrentWS = ActiveSheet
Dim SourceWS As Worksheet
Set SourceWS = Workbooks("Workbook1.xlsx").Worksheets("Sheet1")
Dim SourceHeaderRow As Integer: SourceHeaderRow = 1
Dim SourceCell As Range, sRange As Range, Rng As Range
Dim TargetWS As Worksheet
Set TargetWS = Workbooks("Workbook2.xlsm").Worksheets("Sheet2")
Dim TargetHeader As Range
Set TargetHeader = TargetWS.Range("A1:AX1")
Dim RealLastRow As Long
Dim SourceCol As Integer
Range("B2").Select
SourceWS.Activate
LastCol = Sheets("Sheet1").Cells(1, Columns.Count).End(xlToLeft).Column
Set sRange = Sheets("Sheet1").Range("A1", Cells(1, LastCol))
With sRange
Set Rng = .Find(What:="Sort", _
After:=.Cells(1), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False)
If Not Rng Is Nothing Then
LastRow = Sheets("Sheet1").Cells(Rows.Count, Rng.Column).End(xlUp).Row
Sheets("Sheet1").Range(Rng, Cells(LastRow, Rng.Column)).Copy
TargetWS.Activate
Sheets("Sheet2").Range("B1").Paste
End If
End With
End Sub
Workbook1.xlsx and Workbook2.xlsm have to be open for the code bellow
Option Explicit
Public Sub CopyProjectName()
Dim sourceWS As Worksheet, targetWS As Worksheet
Dim lastCol As Long, lastRow As Long, srcRow As Range
Dim found1 As Range, found2 As Range
Set sourceWS = Workbooks("Workbook1.xlsx").Worksheets("Sheet1") 'Needs to be open
Set targetWS = Workbooks("Workbook2.xlsm").Worksheets("Sheet2") 'Needs to be open
With sourceWS
lastCol = .Cells(1, Columns.Count).End(xlToLeft).Column
Set srcRow = .Range("A1", .Cells(1, lastCol))
Set found1 = srcRow.Find(What:="Sort", LookAt:=xlWhole, MatchCase:=False)
If Not found1 Is Nothing Then
lastCol = targetWS.Cells(1, Columns.Count).End(xlToLeft).Column
Set srcRow = targetWS.Range("A1", targetWS.Cells(1, lastCol))
Set found2 = srcRow.Find(What:="Name", LookAt:=xlWhole, MatchCase:=False)
If Not found2 Is Nothing Then
lastRow = .Cells(Rows.Count, found1.Column).End(xlUp).Row
.Range(.Cells(2, found1.Column), .Cells(lastRow, found1.Column)).Copy
found2.Offset(1, 0).PasteSpecial xlPasteAll
End If
End If
End With
End Sub