Reputation: 31
I have a spreadsheet where users paste numbers, due to the length of these numbers (and the fact that we don't need to spreadsheet to carry out any computations with them) we want them to be formatted as text, otherwise they appear in scientific format i.e. 1.12345E+13
instead of 12345678912345
It is not possible to adjust/modify the data source the numbers are being copied from.
I'm using Private Sub Workbook_SheetChange
do detect if a cell in the relevant range has been changed, and I then format the range to text with
ThisWorkbook.Sheets("Sheet1").Columns("B").NumberFormat = "@"
Unfortunately on Excel 2007 whether you do this manually in Excel or via a marco, the number still appears as 1.12345E+13
unless you click into the cell and press enter.
I can get round this by applying:
With rng
.Value = Evaluate("IF(ISTEXT(" & .Address & "),TRIM(" & .Address & "),REPT(" & .Address & ",1))")
End With
but when I do this I end up with an infinite loop, as the Private Sub Workbook_SheetChange
detects the cell has been changed and goes round the loop again.
If I could somehow work out whether the cell has been changed manually by the user or by the macro, this would be easily fixed. The macro is in ThisWorkbook
. I've tried using Application.Activesheet
instead of ThisWorkbook.Sheets
but it didn't make any difference.
If alternatively there's an easier/better way to fix numbers being displayed as 1.12345E+13
even after I've re-formatted the cell I'd love to know about it.
Thank you.
Upvotes: 3
Views: 1190
Reputation: 166306
Here's a full example, including handling Target ranges of >1 cell:
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
Dim c As Range
Application.EnableEvents = False
On Error GoTo haveError
For Each c In Application.Intersect(Target, Sh.UsedRange).Cells
With c
If IsNumeric(.Value) Then
.NumberFormat = "@"
.Value = CStr(.Value)
End If
End With
Next c
haveError:
'Make sure to re-enable events!
Application.EnableEvents = True
End Sub
Upvotes: 5
Reputation: 17637
but when I do this I end up with an infinite loop, as the Private Sub Workbook_SheetChange detects the cell has been changed and goes round the loop again.
That's because you need to disable application events from automatically firing.
Private Sub Workbook_SheetChange(ByVal Sh As Worksheet, ByVal Target As Range)
Application.EnableEvents = False '// Stop events automatically firing
With rng
.Value = Evaluate("IF(ISTEXT(" & .Address & "),TRIM(" & .Address & "),REPT(" & .Address & ",1))")
End With
Application.EnableEvents = True '// Re-enable events for next time
End Sub
Because you've disabled the events, it can't trigger itself again when you change the value of the cell. Once the code has completed you can re-enable the events to ensure that it fires the next time it is required.
For what it's worth, don't beat yourself up about it - this is an extremely common pitfall when people start working with event procedures in excel-vba.
Upvotes: 5