I have a large amount data in an Excel file. I have over 3000 rows which cross A to CZ columns.
Before I start using the data, I need to trim all of it.
When I use VBA it takes a long time and I get error "Type not match".
Some cells contain space, some contain formula, some contain formula link with another Excel file.
Worksheets("Sheet1").Activate
For Each cell In ActiveSheet.UsedRange.SpecialCells(xlCellTypeConstants)
If cell.HasFormula = False Then
cell.Value = Trim(cell)
End If
Next cell
It want to trim the cells which do not have a formula but it gets the error.
Text-to-Columns, Fixed width, Finish will quickly remove leading/trailing spaces.
dim i as long
with Worksheets("Sheet1")
for i=.cells(1, .columns.count).end(xltoleft).column to 1 step -1
with .columns(i)
.cells.TextToColumns Destination:=.cells(1), DataType:=xlFixedWidth, _
FieldInfo:=Array(0, 1)
end with
next i
end with
BTW, if you want to reduce multiple interim spaces (e.g. data data to data data) to a single space, you need to use Application.Trim(...) not VBA.Trim(...).
Worksheets("Sheet1").Activate
For Each cell In ActiveSheet.UsedRange
If Not IsError(cell) Then
cell = WorksheetFunction.Trim(cell)
End If
Next cell
finally i use this code to ignore the error. i know it is not a good method.
Related
I am trying to create a script that finds individual receipts from a combined.csv document that is generated after a series of scripts performs other processing on the data. I would like to take the ID number of the receipt and split it out across different sheets in the same workbook. Here's what I have so far:
Sub CleanData()
Range("A:A").Sort Key1:=Range("A:A"), Order1:=xlDescending, Header:=xlYes
Range("W1").Value = "Receipt Number"
Range("W2").Value = Left(Range("A2"), 4)
End Sub
This effectively copy over one line of data, but I am struggling to find a way to get it to grab the entire contents of the column, take the first 4 characters of the cell and then copy the entire contents of that into another column.
Thank you in advance!
I would recommend using a Formula, automatic Fill-Down, and then converting to values:
'Column W to same length as Column A
With Range(Range("W2"), Cells(Rows.Count,1).End(xlUp).Offset(0,22))
.Formula = "=Left(A2, 4)" 'Apply Formula, with auto-fill-down
.Calculate 'Calculate results of Formulae
.Value = .Value 'Convert Formulae to Values
End With
Yesterday I learned here how to copy a row to a second sheet.
Sub maJolieProcedure(Texte As String)
With Worksheets("employes").Range("A:A")
Set c = .Find(what:=Texte)
If Not c Is Nothing Then
firstAddress = c.Row
Worksheets("employes").Rows(firstAddress).Copy _
Destination:=Worksheets("rapport").Range("A1")
MsgBox "Ok"
Else
MsgBox "Nok"
End If
End With
End Sub
To respect the formatting of the second sheet, I want to copy and paste the contents of each cell one by one.
I can identify the line number. However, I can't figure out how the Range object can return each cell one by one. For example, C3 content if Rows = 3.
Thanks a lot.
If you don't want to paste the formatting from one range to another paste values only.
Worksheets("employes").Rows(firstAddress).Copy
Worksheets("rapport").Range("A1").PasteSpecial xlValues
That's the same for all ranges, whether 1 cell or a million. The Copy process copies the subject to memory as one block. Any parsing must be done before the Copy instruction. An alternative is to read a range into an array.
Dim Arr As Variant
Arr = Worksheets("employes").Rows(firstAddress).Value
This will create a 3D array of 1 row and about 16000 columns. You might decide to limit your enthusiasm to only what you need.
With Worksheets("employees")
Arr = .Range(.Cells(firstAddress, 1), .Cells(firstAddress, .Columns.Count).End)xlToLeft)).Value
End With
Pay attention to the leading periods within the With statement. Each such period stands for the object mentioned in the With statement.
If your goal is to respect the formating of the second sheet, you don't need to loose time copying cell by cell.
It is more effective to do a paste special, like you do with the mouse:
Range("A1").Copy
Range("B1").PasteSpecial Paste:=xlPasteValues
works very well also with bigger ranges if you need:
Range("A1:A12").Copy
Range("B1:B12").PasteSpecial Paste:=xlPasteValues
or even
Range("A1:A12").Copy
Range("D3").PasteSpecial Paste:=xlPasteValues
If your goal is to really access all cell of a range individually , you just iterate on the range. For example:
For Each cell In Range("A1:A12")
cell.Value = cell.Value + 2
Next cell
I am new to vba coding (and coding in general) but I have started doing a small macro that transfers values of a csv file into an excel file.
My next step is to remove the quotation marks in each cell. I have tried these lines of codes in my sub:
Dim Table As Range
Dim Cell As Variant
Set Table = Range("A1:currentregion")
For Each Cell In Table
cell.value2 = Replace(cell.value2,""","") *I get a syntax error here*
Next Cell
I know this is very basic but I can't find a solution on the net or using the macro recorder. If anybody could tell me what I am doing wrong and also what code I could use to change the value in a cell that contains a string of numbers into a numeric value?
Thanks!
You don't need to loop through each cell. The Range("A1").CurrentRegion may be operated on as a whole.
With Range("A1").CurrentRegion
.Replace What:="""", Replacement:=vbNullString, LookAt:=xlPart
End With
Note that to look for a single quote (e.g. ") you need 4 quotes in a row. An alternative is Chr(34) as a quote symbol is the 34th ASCII character.
Addendum:
With regard to the second portion of your question, changing text that looks like a number to actual numbers is best done with a quick Text to Columns ► Fixed Width command. Each column would have to be run through individually but this can be accomplished within the .CurrentRegion.
Dim c As Long
With Range("A1").CurrentRegion
.Replace What:="""", Replacement:=vbNullString, LookAt:=xlPart
For c = 1 To .Columns.Count
.Columns(c).NumberFormat = "General"
.Columns(c).TextToColumns Destination:=.Columns(c), _
DataType:=xlFixedWidth, FieldInfo:=Array(0, 1)
Next c
End With
There is the question of what number format the columns were in to begin with. If they were Text (e.g. '.NumberFormat = "#"` then removing the quotes is not going to convert them to true numbers. I've added a reversion to the General number format to accommodate this. If you have existing number formats that you wish to keep, there are more precise ways of reverting the number formats of some of the cells.
Cell.Value2 = Replace(Cell.Value2, Chr(34), "")
There always is a workaround, this one is referencing via character code.
You should dim Cell as Range. Also it's not a very good idea to name a variable using a VBA syntax element. Use MyTable and MyCell instead.
And to set the range better use
Set MyTable = [A1]
For Each MyCell In MyTable.CurrentRegion
...
In excel, I have a text string, which contains numbers and text, that I strip the numbers out of with a formula. However, sometimes it is possible that the text string will be blank to begin with so if this happens I use "" to return a blank instead of a 0. When I link this excel sheet to an access database it will not let me format this column as currency because it is picking up the "" as text along with the stripped out numbers as numbers. Any solutions on how to fix this? Is there another way besides "" to make a cell completely blank and not a zero length string?
This is along the lines of the problem I am having:
http://support.microsoft.com/kb/162539
Here is a quick routine that reduces formulas to their values and strips zero length strings to truly blank cells.
Sub strip_zero_length_string()
Dim c As Long
With Sheets("Sheet1").Cells(1, 1).CurrentRegion
.Cells = .Cells.Value
For c = 1 To .Columns.Count
.Columns(c).TextToColumns Destination:=.Cells(1, c), _
DataType:=xlFixedWidth, FieldInfo:=Array(0, 1)
Next c
End With
End Sub
I'm using .CurrentRegion so there can be no completely blank rows or columns within your data block but that is usually the case when preparing to export to a database.
I'm using VBA to do some further formatting to a generated CSV file that's always in the same format. I have a problem with my For Each Loop. the loop deletes an entire row if there is more than one blank row which can be determined from the first column alone.
Dim rowCount As Integer
For Each cell In Columns("A").Cells
rowCount = rowCount + 1
'
' Delete blank row
'
If cell = "" And cell.Offset(1, 0) = "" Then
Rows(rowCount + 1).EntireRow.Delete
spaceCount = 0
End If
Next
At some point the value in the loop one of the calls does not have a value of "", it's just empty and causes it to crash. To solve this I think that changing the type of the cell to text before that compare would work but I can't figure out how (no intellisense!!!)
So how do you convert a cell type in VBA or how else would I solve the problem?
Thanks.
Use cell.Value instead of the cell.Text as it will evaluate the value of the cell regardless of the formating. Press F1 over .Value and .Text to read more about both.
Be carefull with the statement For Each cell In Columns("A").Cells as you will test every row in the sheet (over a million in Excel 2010) and it could make Excel to crash.
Edit:
Consider also the funcion TRIM. It removes every empty space before and after a string. If in the cell there is a white space " "; it will look like empty for the human eye, but it has a space inside therefore is different than "". If you want to treat it like an empty cell, then try:
If Trim(cell.value) = "" then
As #andy (https://stackoverflow.com/users/1248931/andy-holaday) said in a comment, For Each is definitely the way to go. This even allows for there to be spaces in between lines.
Example code:
Sub ListFirstCol()
Worksheets("Sheet1").Activate
Range("A1").Activate
For Each cell In Application.Intersect(Range("A:A"), Worksheets("Sheet1").UsedRange)
MsgBox (cell)
Next
End Sub
Thanks Andy!