VBA: How to keep my csv format when transferring excel data to it? - vba

I have a csv file that I have separated based on commas. I'm using a csv file because I'm using it as a "master" file to hold a lot of information but I would prefer columns rather than having it separated by commas.
So the code I need is to be able to run a macro that will take cells from my "copy" excel workbook, and move append it to where the new blank cells begin at the bottom of my "master" csv file.
For example:
A B C
Week Time Month
3 09:03 March
My Master.csv will have the same column headings and I will want to continually update the Master.csv when I get new info from my copy.xlsx which is updated weekly.
Sub move2()
Dim x As Workbook
Dim y As Workbook
Dim vals As Variant
'Open workbooks
Set x = Workbooks.Open("C:\Users\wra\Desktop\macro test\copy")
Set y = Workbooks.Open("C:\Users\wra\Desktop\macro test\Master.csv")
'Store value in variable
vals = x.Sheets("copy").Range("A5").Value
'Use the variable to assign a value to the other file/sheet:
y.Sheets("Master").Range("A3").Value = vals
'Close x:
x.Close
End Sub
I know this code doesn't do what I want full yet (only takes one value and adds it to a specific place in the master.csv, but it's a start I guess.
The thing is, when I run this macro, information from my copy.xlsx is moved to the Master.csv, BUT the master.csv gets reformatted from columns to text.
So after the macro is run it looks like the following:
A
Week,Time,Month
3,09:03,March
All the data goes back to one column and the Text to Columns function I used before hand is removed.
How can I prevent this from happening? And if anyone can help with the next part of code (where I want it to append to the bottom of my master.csv data, that would be awesome.
Hope this was clear, thanks in advance!

As David said, use Workbooks.OpenText to ensure your master file is opened correctly, e.g.:
Set y = Workbooks.OpenText("C:\Users\wra\Desktop\macro test\Master.csv", DataType:=xlDelimited, Comma:=True)
To append to the bottom of the master file, you will need to find the last row in the file, and input your data below that. There are many ways to find the last row in Excel, but one method is to do the following:
myLastRow = y.Sheets("Master").Cells(Rows.Count, 1).End(xlUp).Row
which finds the last row in in the first column of the "Master" sheet. The new data could then be copied in like so:
y.Sheets("Master").Cells(myLastRow + 1, 1).Resize(number_rows, number_cols).Value = vals

Related

Excel macro - how to break wrapped text into rows for merged columns?

I have to import data from PDF to SAS, and one step involves converting the PDF data to excel spreadsheet before converting to text for simpler SAS import. Usually the PDF data converts fine into excel, with few errors. As I am trying to import older data, it is getting quite messy and some of the rows get wrapped in a single cell. I am trying to figure out if there is a macro possible which can help me fix this error in sheets without too much manual manipulation. I have never programmed in VBA before so I am quite new to excel macros.
Here is the example of messy data:
Here is the example of normal data:
(*Note the data values in the two images are different, just for example formatting)
I have tried working on a macro. For this, I copy the messy data into another sheet, and run the macro which outputs corrected data on a separate sheet, and then i copy the corrected data over the messy one in the original spreadsheet.
After trying to code the macro, I was unable to figure out how to tell excel to take the data in columns C,D,E,F which are all merged into one cell and break that wrapped text, and so on for other merged columns (as shown in messy data image).
Here is my current code that I got after watching some tutorials:
Sub Split_Text_to_Rows()
Dim splitVals1 As Variant
Dim splitVals2 As Variant
Dim totalVals As Long
Set sh1 = ThisWorkbook.Sheets(2)
Set sh2 = ThisWorkbook.Sheets(3)
sh2.Cells.Clear
lrow1 = sh1.Range("A65356").End(xlUp).Row
For j = 1 To lrow1
splitVals1 = Split(sh1.Cells(j, 1), Chr(10))
splitVals2 = Split(sh1.Cells(j, 2), Chr(10))
For i = LBound(splitVals1) To UBound(splitVals1)
lrow2 = sh2.Range("A65356").End(xlUp).Row
sh2.Cells(lrow2 + 1, 1) = splitVals1(i)
Next i
For k = LBound(splitVals2) To UBound(splitVals2)
lrow3 = sh2.Range("B65356").End(xlUp).Row
sh2.Cells(lrow3 + 1, 2) = splitVals2(k)
Next k
Next j
End Sub
As you can see, my code is also quite messy. Although, I got the code to work for columns A and B, when I get to column C - "Motor Vehicle Theft" and so on, I am not sure how to separate that wrapped text since they are merged in columns C,D,E,F. I would also like to keep the columns I to Q as two merged rows even after macro splits 1 row into 2 (shown in normal data image) and then continue splitting cells till column Z.
Any tips would be helpful! Please let me know if more information or clarification is needed.
I often find that the best approach is to first paste the data into Word, do some clean-up there, format it as a Word table, and then transfer it into Excel. The reason is that Word has very powerful find/replace features which allow you to quickly convert a mess into something sensible. Since you didn't provide example data I could paste in, I randomly found a pdf on the web to show one approach. The key in this case was noticing that each column begins with a space followed by a digit. So I did a search for " ^#" (a space followed by 'any digit') and replaced it by "^t" (tab character). Next, I used Word's 'Convert to Table' feature, and after that the data table is ready for pasting into Excel.

Lose data in long strings when transfering values using ranges

So, I'm working on a project and at one point I copy data from one workbook to another by setting a range on the one workbook and then setting the range on the destination workbook equal to it. This works great in general, but I have one field that under some circumstances has data that is five digit numbers separated by commas. Zip codes essentially, separated by commas and possibly spaces as well. (Although there aren't supposed to be spaces in that data it is very possible that there are.)
So for example the cell being copied will look like this:
11111,22222,33333,44444,55555,66666,77777,88888,99999
and will transfer as this:
1.11112222233333E+44 or
111,112,222,233,333,000,000,000,000,000,000,000,000,000,000
This is obviously not what I want. How do I fix this?
Here is the relevant code. The column that has the problem data is column F of the Service Areas worksheet.
Dim MainWB As Workbook
Set MainWB = Workbooks("SATemplate Data Compile.xlsm")
Dim MDSAT As Range
'Setting the range I want to transfer
Set MDSAT = wb.Worksheets("Service Areas").Range("A13:G13", wb.Worksheets("Service Areas").Range("A13:G13").End(xlDown).End(xlDown).End(xlUp))
'Transferring the range values
MainWB.Sheets("SATemplates").Range("A" & Rows.count).End(xlUp).Offset(1).Resize(MDSAT.Rows.count, MDSAT.Columns.count).Cells.Value = MDSAT.Cells.Value
Is this a problem with setting the new range equal to the cell values? Would I have to split this up into multiple parts so that a different range will grab the data in column F?
Try this (to force as values (text)):
With MainWB.Sheets("SATemplates").Range("A" & Rows.count).End(xlUp).Offset(1).Resize(MDSAT.Rows.count, MDSAT.Columns.count)
.NumberFormat = "#" 'format as text
.Value = MDSAT.Value
End With
Format the cells as text not numbers....

Copying Cells from other workbooks into one workbook automatically

I have many excel files of the same structure in one folder (Sample 1, Sample 2......Sample 20). I created another excel file in the same folder that needs to pull out information from each other excel file (Results). There is a specific column in each Sample file that I need to copy and paste into a row in the Results file. I am trying to create a tool or Macro that can, from a push of a button, extract the same column from each file and paste it into a new row in the Results file. I cannot alter anything in the Sample files and this should be done automatically without opening each file. Also new Sample files will be added to the folder (Sample 21...22 etc) so the function should be able to pull from the new files.
Edit.
Based off of Pomul's suggestion of transposing the rows. I came up with the following code and results. Right now I am testing the code to transpose in the same worksheet:
Transpose Image Screenshot
Please let me know why my code makes another column instead of transposing it into a row.
This seems to work:
Sub Button1_click()
Dim i&, z&, x&
i = Worksheets("Sheet2").Cells(Rows.Count, "B").End(xlUp).Row
z = 1: x = 1
While z <= i
Worksheets("Sheet1").Range("A" & x).Resize(, i) = _
WorksheetFunction.Transpose(Worksheets("Sheet2").Range("B" & z).Resize(i))
z = i + 1
Wend
End Sub

Excel 2013: Use macro to copy and subsequently add data from one sheet to another within same workbook

I have used the various methods pointed out in this forum and none seem to work, so I will try to be more specific.
I have a workbook called LIBRARY.xlsm.
This workbook contains two worksheets: CALCULATOR and CUTS.
The worksheet CALCULATOR contains two tables: INPUT and OUTPUT.
I enter data into INPUT, values are calculated and automatically entered into OUTPUT.
I create a button below OUTPUT with macro to copy data in OUTPUT to worksheet CUTS.
I enter new data into INPUT, which then updates OUTPUT.
Now I want to copy this new data to CUTS without overwriting or deleting previous data.
Since this project is divided into 5 sections, I should end up with five tables in the worksheet CUTS that I can then print out.
The INPUT table encompasses cells A1:M31, which does not matter (I’m not copying this).
The OUTPUT table occupies cells O6:S26. This is the data that needs to be copied.
Placement into worksheet CUTS can start at cell A1 (which means the table will have the range A1:E20). I would like to skip a column and then place the next data set. Thus, the next data set should begin at G1 (G1:K20), then at M1:Q20 and so forth). Maybe only go three tables across and then start next three below (separated by row).
Here is the code tried to use. Problem is, it does not retain the values and it overwrites the previous data.
Sub Create_CUTS ()
Dim sourceSheet As Worksheet
Dim sourceRange As Range
Dim sourceRows As Integer
Set sourceSheet = Worksheets("CALCULATOR")
sourceRows = WorksheetFunction.CountA(sourceSheet.Range("A:A"))
Set sourceRange = sourceSheet.Range("O6:S26" & sourceRows)
Dim targetSheet As Worksheet
Dim targetRange As Range
Dim targetRows As Integer
Set targetSheet = Worksheets("CUTS")
targetRows = WorksheetFunction.CountA(targetSheet.Range("A:A"))
Set targetRange = targetSheet.Range("A" & targetRows + 1 & ":A" & targetRows + 1 + sourceRows)
sourceRange.Copy Destination:=targetRange
End Sub
Thank you, everyone
-Grumps
There are a few ways to do this. The easiest is probably to just reference the usedrange of the target sheet to know where you left off with the last paste.
lastUsedRow = targetSheet.UsedRange.Rows.Count
lastColumnUsed = targetSheet.UsedRange.Columns.Count
Then you just add a column or row and paste the table in the new location. If the column count is 22 or greater, add a row and paste at "A" and the lastUsedRow + 2. There is some potential for this to be wrong if the sheets are saved with cells that are empty, but excel reads them as "used" (somehow people I work with manage to do this all the time, I don't even know how they do it). It sounds like this is something that users won't be manipulating, so I wouldn't think that would be a problem, but if it is a possible problem for you, you can use a loop to find the next empty cell instead of using the built in "usedrange" collection.

Copy data from multiple excel sheets and append that to a single excel sheet using VBScript

The scenario is as follows:
I have an excel (.xls) file with data. (eg. A.xls)
The Data on this excel file are on a single worksheet (Sheet 1).
The number of columns in this file is fixed i.e. 8
However, the number of rows containing data may vary from time to time. (This file is updated by another program from time to time)
Now, I have another excel file (eg. B.xls) with similar type of data but not same as the contents of A.xls.
The number of columns in B.xls is 8 as well. However, the number of rows containing data are unknown.
I want to copy the contents of A.xls, 2nd row onwards (excluding the 1st row containing the column headers) and append/paste the same to the B.xls file, without over-writing the existing data on B.xls.
With all these details in mind, I want to write a vbscript to automate this task.
Please help.
Thanks a lot, in advance.
It needs a lot of cleanup, but something like this should work. I'll clean it up a bit and then make an edit.
Sub CopyRows()
' Choose the name of the Second Workbook and last column.
' It must be in the same directory as your First Workbook.
secondWorkbook = "B.xls"
lastColumn = "H"
' A couple more variables
currentWorkbook = ThisWorkbook.Name
Workbooks.Open ThisWorkbook.Path & "\" & secondWorkbook
' In the First Workbook, find and select the first empty
' cell in column A on the first Worksheet.
Windows(currentWorkbook).Activate
With Worksheets(1).Columns("A:A")
Set c = .Find("", LookIn:=xlValues)
If Not c Is Nothing Then
' Select and copy from A2 to the end.
secondAddress = Replace(c.Address, "$A$", "")
Range("A2:" & lastColumn & CStr(CInt(secondAddress) - 1)).Select
Selection.Copy
End If
End With
' Activate the Second Workbook
Windows(secondWorkbook).Activate
With Worksheets(1).Columns("A:A")
Set c = .Find("", LookIn:=xlValues)
If Not c Is Nothing Then
' Select and paste the data from First Workbook
Range(c.Address).Select
ActiveSheet.Paste
End If
End With
End Sub
Update: That should do the trick. I copied from the wrong workbook the first time around, too. Let me know if you have questions.
This is something the Macro Recoder could have written for you. You would come out with different approach.
Turn on recording. Open A.xls and B.xls. Move down one row on a. Press Shift+End then →, then Shift+End+↓. Then Ctrl+C to copy your data. Switch back to B. End+↓, ↓. Ctrl+V to paste. Turn off recording.
You can record in Excel.
Alt+T,M,R
then Home key then ↑. Stop recording.
Look what Excel wrote
Selection.End(xlUp).Select
or if you had of recorded Go To dialog
Application.Goto Reference:="R1C1"
or if you had of recorded Ctrl+Home
Range("A1").Select
To convert to vbscript
Record the steps in excel macro recorder. You have to rewrite it a bit because it uses a type of syntax that vbs doesn't.
This applies (I don't have a medium9) xlRangeAutoFormatAccounting4 in vba.
Selection.AutoFormat Format:=xlRangeAutoFormatAccounting4, Number:=True, _
Font:=True, Alignment:=True, Border:=True, Pattern:=True, Width:=True
So first look up constants in vba's object browser. xlRangeAutoFormatAccounting4 = 17
Then look the function up in object browser and look at the bottom for the function definition,.
Function AutoFormat([Format As XlRangeAutoFormat = xlRangeAutoFormatClassic1], [Number], [Font], [Alignment], [Border], [Pattern], [Width])
So the vba becomes in vbs (and vbs works in vba) (and as you can see you can work out the correct way without needing to look the function up usually)
Selection.AutoFormat 17, True, True, True,True, True, True
So your code becomes
objXLWs.Range("A3").CurrentRegion.Select.AutoFormat 17, True, True, True,True, True, True