Microsoft Excel cells basically have two values: the formatted value that is shown to the user, and the actual value of the cell. These two values can be extremely different when the cell has certain formatting types such as date, datetime, currency, numbers with commas, etc.
I am writing a script that cleans up database data. It uses find, replace, RegEx, and other functions that act on strings of text. I need to be able to convert data into very specific formats so that my upload tool will accept the data. Therefore I need all of the cells in my Excel spreadsheets to be TEXT. I need the displayed values to match the actual values.
This is surprisingly hard to do in Excel. There is no paste special option that I could find that pastes what you see on your screen as text. "Paste Special -> Values" pastes, predictably, unformatted values. So if you try to "Paste Special -> Values" into cells formatted as TEXT, and they are coming from cells formatted as DATES, you might get something like this:
Old Cell: 4/7/2001
New Cell: 36988
If you paste normally, then the paste goes in as 4/7/2001, but in date format. So if I create a RegEx that looks for 4/7/2001 and changes it to 4/7/01, it will not work, because the underlying value is 36988.
Anyway, I discovered the Cell.Text
property and wrote some code that converts all cells in a spreadsheet from formatted to text. But the code has two major problems:
1) It does not work on cells with more than 255 characters. This is because Cell.Text
literally displays what the cell is actually showing to the user, and if the column is too narrow, it will display pound signs (########
), and columns have a maximum width of 255 characters.
2) It is extremely slow. In my 1.5 million cell test sheet, code execution took 394 seconds.
I'm looking for ideas to optimize the code's speed, and to make the code work on all display value lengths.
Function ConvertAllCellsToText()
' Convert all cells from non-text to text
' This is helpful in a variety of ways
' Dates and datetimes can now be manipulated by replace, RegEx, etc., since their value is now 4/7/2001 instead of 36988
' Phone numbers and zip codes won't get leading zeros deleted if we try to add those
StartNewTask "Converting all cells to text"
' first draft of the code, does not work as intended, dates get scrambled
'Cells.Select
'Selection.Copy
'Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
'Application.CutCopyMode = False
Dim MyRange As Range
Set MyRange = ActiveSheet.UsedRange
' prevent Cell.Text from being ########
MyRange.ColumnWidth = 255
Dim i As Long
Dim CellText As String
For Each Cell In MyRange
If Cell.Text <> Cell.Value And Len(Cell.Value) <= 255 Then
CellText = Cell.Text
Cell.NumberFormat = "@"
Cell.Value = CellText
End If
i = i + 1
If i Mod 2500 = 0 Then
RefreshScreen
End If
Next
MyRange.ColumnWidth = 20
' set all cells to Text format
Cells.Select
Selection.NumberFormat = "@"
End Function