Remove dot in string, issue with numbers < 1000 - excel

I have a column with data taken from CSV file, the data contain the dot I need to remove. When I want to replace „.“(dot) with „“ (nothing) with VBA I have a wrong result. All numbers smaller than 1000 replace the comma, I have for example 122,49 and the result is 12249 which is wrong.
I tried several VBA codes, non of them worked.
If you can help me it would be great. I tried all options with formats..
Thank you.
2.078,00 -> 2078,00 ok
122,49 -> 12249 ko
328,28 -> 32828 ko
11.192,34 -> 11192,34 ok
Sub TEST()
Dim i As String
Dim k As String
i = "."
k = ""
Columns("P:P").Replace what:=i, replacement:=k, lookat:=xlPart, MatchCase:=False
End Sub

Actually this is a bug in Excel! It only happens in VBA. If you do the same replace from the user interface it works. The same from a recorded macro fails. So obviously a bug.
I recommend to read all the values into an array, then replace and then write them back. This way the error does not occur and using arrays is even faster than using ranges.
Option Explicit
Sub TEST()
Dim i As String
Dim k As String
i = "."
k = ""
Dim LastRow As Long 'find last used row (to reduce processed cells)
LastRow = Cells(Rows.Count, "P").End(xlUp).Row
Dim ReplaceValues() As Variant 'read all values into array
ReplaceValues = Range("P1:P" & LastRow).Value
Dim iRow As Long 'replace
For iRow = LBound(ReplaceValues) To UBound(ReplaceValues)
ReplaceValues(iRow, 1) = Replace(ReplaceValues(iRow, 1), i, k)
Next iRow
'write all values from array back into cells
Range("P1:P" & LastRow).Value = ReplaceValues
End Sub
Or, use Application.Substitute:
Sub Test()
Dim lr As Long
Dim arr As Variant
lr = Cells(Rows.Count, "P").End(xlUp).Row
arr = Range("P1:P" & lr).Value
Range("P1:P" & lr).Value = Application.Substitute(arr, ".", "")
End Sub

I'm not sure if I exactly understand your requirements, but see if this is doing what you want.
Function RemovePeriods(ByVal number As String) As String
RemovePeriods= Replace(number, ".", ",")
RemovePeriods= Replace(Left$(RemovePeriods, Len(number) - 3), ",", "") & Right$(RemovePeriods, 3)
End Function
'run from here
Sub Example()
Debug.Print RemovePeriods("2.078,00")
Debug.Print RemovePeriods("122,49")
Debug.Print RemovePeriods("328,28")
Debug.Print RemovePeriods("11.192,34")
End Sub
Output
2078,00
122,49
328,28
11192,34

Give this a try:
Sub dotKiller()
For Each cell In Intersect(Range("P:P"), ActiveSheet.UsedRange)
v = cell.Text
If InStr(v, ".") > 0 Then
cell.Clear
cell.NumberFormat = "#"
cell.Value = Replace(v, ".", "")
End If
Next cell
End Sub
If the cell does not contain a dot it will not be changed.
Before:
and after:

Try this
Sub Test()
Columns("P:P").Replace What:=Application.DecimalSeparator, Replacement:="", LookAt:=xlPart, MatchCase:=False
End Sub
Or manually File >> Options >> Advanced >> Uncheck (Use system separators)

Related

I have a Product Name like this. I run vba code for extracting date, am not getting the result, it shows error

Code:
Sub My_Date()
Dim endRow As Long
endRow = Cells(rows.Count, "B").End(xlUp).row
ActiveCell.FormulaR1C1 = _
"=DATEVALUE(IF(LEFT(RIGHT(LEFT(RC[1],FIND(CHAR(1),SUBSTITUTE(RC[1],""_"",CHAR(1),5))-1),FIND(CHAR(1),SUBSTITUTE(RC[1],""_"",CHAR(1),5))-FIND(CHAR(1),SUBSTITUTE(RC[1],""_"",CHAR(1),4))-1),3)=TEXT(TODAY()-1,""Mmm""),RIGHT(LEFT(RC[1],FIND(CHAR(1),SUBSTITUTE(RC[1],""_"",CHAR(1),5))-1),FIND(CHAR(1),SUBSTITUTE(RC[1],""_"",CHAR(1),5))-FIND(CHAR(1),SUBSTITUTE(RC[1],""_"",CHA" & _
"-1),IF(LEFT(RIGHT(LEFT(RC[1],FIND(CHAR(1),SUBSTITUTE(RC[1],""_"",CHAR(1),6))-1),FIND(CHAR(1),SUBSTITUTE(RC[1],""_"",CHAR(1),6))-FIND(CHAR(1),SUBSTITUTE(RC[1],""_"",CHAR(1),5))-1),3)=TEXT(TODAY()-1,""Mmm""),RIGHT(LEFT(RC[1],FIND(CHAR(1),SUBSTITUTE(RC[1],""_"",CHAR(1),6))-1),FIND(CHAR(1),SUBSTITUTE(RC[1],""_"",CHAR(1),6))-FIND(CHAR(1),SUBSTITUTE(RC[1],""_"",CHAR(1),5)" & _
""")))"
range("B2").Autofill Destination:=range("B2:B" & endRow)
End Sub
You could write your own function.
This will split your text by the _ delimiter and return the bit that can be turned into a date.
Sub Test()
Dim endRow As Long
With ThisWorkbook.Worksheets("Sheet1")
endRow = .Cells(.Rows.Count, 2).End(xlUp).Row
.Range(.Cells(2, 1), .Cells(endRow, 1)).FormulaR1C1 = "=ExtractDate(RC2)"
End With
End Sub
Public Function ExtractDate(Target As Range, Optional Delim As String = "_") As Variant
Dim SplitText As Variant
SplitText = Split(Target, Delim)
Dim Itm As Variant
For Each Itm In SplitText
If IsDate(Itm) Then
ExtractDate = CDate(Itm)
Exit For
End If
Next Itm
'If no date found return an #N/A error.
If ExtractDate = 0 Then ExtractDate = CVErr(xlErrNA)
End Function
The cell reference in the Test procedure "=ExtractDate(RC2)" is in the R1C1 format - it means this row (where the formula appears), column 2.
The solution proposed by Darren Bartrup-Cook has a serious pitfall: IsDate and CDate functions work with the month names in a current locale. Which means that in general case they do not recognize May 03 and alike as a date
Let's make it work. Here are the assumptions about our data:
There's a pattern in Product Names with _ as a delimiter: the date always comes sixth in a row.
The year is always meant to be the current one.
The name of the month is always indicated in full.
Function ExtractDate(Text As String)
Const Delimiter = "_"
Const Position = 5 ' starting from zero
ExtractDate = Split(Text, Delimiter)(Position)
End Function
Sub Main_Macro()
Dim Source As Range
Dim DateArea As Range
Set Source = Range(Range("B2"), Range("B2").End(xlDown))
Set DateArea = Source.Offset(0, -1)
With DateArea
.NumberFormat = "[$-409]mmmm d"
.Formula2R1C1 = "=ExtractDate(RC[1])"
.Value2 = .Value2
.NumberFormat = "dd-mm-yyyy"
End With
End Sub
Here:
"[$-409]mmmm d" force to recognize months in English
.Value2 = .Value2 replace the formula with real data
.NumberFormat = "mm-dd-yyyy" set the date format in a current locale

How to replace a specific value in a Column on Excel VBA?

I'm trying to replace a specific value in my whole Column D.
My Column looks like this:
COLUMN D
TD10.LU89.AX300.MT01
TD10.LU89.BT100.MT01
TD10.LU89.BP130.MP01
Now what I'm trying to do is to replace only the first "." with ".IO."
This is what I have already tried:
Columns("D").Replace _
What:=".", Replacement:=".IO.", LookAt:=xlPart
and obiviously the result is that all the points will be changed:
TD10.IO.LU89.IO.AX300.IO.MT01
Do you guy have a solution to my problem?
Thank you very much in advance.
You could use:
Option Explicit
Sub test()
Dim LastRow As Long, i As Long
Dim str As String
'Change sheet if needed
With ThisWorkbook.Worksheets("Sheet1")
'Find the last row of column D
LastRow = .Cells(.Rows.Count, "D").End(xlUp).Row
'Loop column D
For i = 1 To LastRow
'Replace the first occurance
str = Replace(.Range("D" & i).Value, ".", ".IO.", , 1)
.Range("D" & i).Value = str
Next i
End With
End Sub
For example
Sub ReplaceDot()
Dim cl As Range
For Each cl In Range("D1:D" & Rows.End(xlUp).Row)
cl.Value = Left(cl.Value, 4) & ".IO." & Right(cl.Value, Len(cl.Value) - 5)
Next cl
End Sub
In case left part is of varying length:
cl.Value = Left(cl.Value, InStr(cl.Value, ".") - 1) & ".IO." & Right(cl.Value, Len(cl.Value) - InStr(cl.Value, "."))
One can make it more universal by adding column and replacement string as params to the sub

How to delete all cells that do not contain specific values (in VBA/Excel)

I fully didn't understand how to follow the answer in vba deleting rows that do not contain set values defined in range (I need to use VBA for this). From what I gathered, i need to specify an array, then use some if then stuff.
In my case, I want to create something that will search just a specified column and delete all values that do not contain specific letters/numbers. 1,2,3,4,5,s,f,p,a,b,c,o are the numbers/letters i want to keep. Cells which do not contain these values (even 11 or 1s should be deleted), I want only to delete the cell (not the whole row) and shift the cells below it up (i believe you can do this with the default .delete command).
For example my columns look like this:
p
a
1
2
5
s
f
s
8
31
4
f
I want to screen my data so that all blank cells and all cells which do not contain the numbers or letter mentioned above (e.g. 31 and 8 in this case) are automatically deleted.
Thanks for your help!
Sub Tester()
Dim sKeep As String, x As Long
Dim rngSearch As Range, c As Range
'C1:C5 has values to keep
sKeep = Chr(0) & Join(Application.Transpose(Range("C1:C5").Value), _
Chr(0)) & Chr(0)
Set rngSearch = Range("A1:A100")
For x = rngSearch.Cells.Count To 1 Step -1
Set c = rngSearch.Cells(x)
If InStr(sKeep, Chr(0) & c.Value & Chr(0)) = 0 Then
c.Delete shift:=xlShiftUp
End If
Next x
End Sub
This will do
Sub Main()
Dim dontDelete
dontDelete = Array("1", "2", "3", "4", "5", "s", "f", "p", "a", "b", "c", "o")
Dim i As Long, j As Long
Dim isThere As Boolean
For i = Range("A" & Rows.Count).End(xlUp).Row To 1 Step -1
For j = LBound(dontDelete) To UBound(dontDelete)
If StrComp(Range("A" & i), dontDelete(j), vbTextCompare) = 0 Then
isThere = True
End If
Next j
If Not isThere Then
Range("A" & i).Delete shift:=xlUp
End If
isThere = False
Next i
End Sub
Sub DeleteValues()
Dim x As Integer
Dim i As Integer
Dim Arr(1 To 3) As String
Arr(1) = "1"
Arr(2) = "2"
Arr(3) = "3"
Range("A1").Select
For x = 1 To 10
For i = 1 To 3
If ActiveCell.Value = Arr(i) Then
ActiveCell.Delete
End If
Next i
ActiveCell.Offset(1, 0).Select
Next x
End Sub
This will loop through range("a1:a10") and delete any cell where the value = any of the array values (1,2,3)
You should hopefully be able to work with this code and suit it to your needs?
Another way :) Which doesn't delete the cells in a loop.
Option Explicit
Sub Sample()
Dim ws As Worksheet
Dim rngDEL As Range
Dim strDel As String
Dim arrDel
Dim i As Long
strDel = "1,11,Blah" '<~~ etc... You can pick this from a range as well
arrDel = Split(strDel, ",")
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws.Columns(1) '<~~ Change this to the relevant column
For i = LBound(arrDel) To UBound(arrDel)
.Replace What:=arrDel(i), Replacement:="", LookAt:=xlWhole, SearchOrder:= _
xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False
Next i
On Error Resume Next
Set rngDEL = .Cells.SpecialCells(xlCellTypeBlanks)
On Error GoTo 0
If Not rngDEL Is Nothing Then rngDEL.Delete Shift:=xlShiftUp
End With
End Sub

Find and delete header columns without a certain word.

I need to:
1. Find a column containing the word 'target' in header. (from the range P1 to QI1 )
2. Delete all other column without 'target' in its header.
Code:
Sub Cleanup()
Dim rng As Range
With ActiveSheet.Range("P1:QI1")
Set rng = ActiveSheet.Range("P1:QI1").Find(What:="target", _
LookAt:=xlPart, MatchCase:=False)
Do While Not rng Is Nothing
rng.EntireColumn.Delete
Set rng = .FindNext
Loop
End With
End Sub
the code above is deleting all the column with the word 'target'. i would like it the other way around. i need to keep those columns.
thanks in advance.
TESTED - enjoy :)
Sub test()
Dim erange As Range
Dim str As String
For Each erange In Range("A1:E1")
If not erange.Value = "Target" Then
' If InStr(erange.Value, "Target") <> 0 Then
If str <> "" Then
str = str & "," & erange.EntireColumn.Address
Else
str = erange.EntireColumn.Address
End If
End If
Next erange
str = Replace(str, "$", "")
' Delete columns in single shot
Range(str).Delete
End Sub

stop excel do-loop until

I have two columns A and B with numbers as values.
In C1 I want =A1 + B1
In C2 I want =A2 + B2
and so on. I have written the following VBA code - while it works it adds "0" after the end of the last row in range.
Let's assume my last row is A10. It adds "0" in C11 when I run the code.
How do I prevent this?
Sub macro()
Dim R As Long
R = 1
Do
Cells(R, "C").Select
R = R + 1
ActiveCell.Formula = "=sum(" & ActiveCell.Offset(0, -2) & "," &
ActiveCell.Offset(0, -1) & ")"
Loop Until IsEmpty(ActiveCell.Offset(0, -2))
End Sub
Just replace your Until condition to the following string:
Loop Until IsEmpty(ActiveCell.Offset(1, -2))
That will check the right cell for being empty. The rest of your code should remain intact.
Take a look at Do Until and Do While and While.
If you really want to iterate over cells you may go ahead. But here a method using Arrays, this will by all means reduces any performance drops that you would get looping over cells...
Option Explicit
Sub AddToRigh()
Dim i As Integer
Dim vArr As Variant
Dim LastRow As Long
'--assume you are working on Sheet 1
LastRow = Sheets(1).Cells(Rows.Count, Range("A1").Column).End(xlUp).Row
ReDim vArr(1 To LastRow)
For i = LBound(vArr) To UBound(vArr)
vArr(i) = "=Sum(RC[-2]:RC[-1])"
Next i
'--output this entire array with formulas into column C
Sheets(1).Range("C1").Resize(UBound(vArr)) = Application.Transpose(vArr)
End Sub
Output:
I'm by no means an expert in vba, but you could do this:
Sub macro()
Dim R As Long
R = 1
Do While Not IsEmpty(ActiveCell.Offset(0, -2))
Cells(R, "C").Select
R = R + 1
ActiveCell.Formula = "=sum(" & ActiveCell.Offset(0, -2) & "," &
ActiveCell.Offset(0, -1) & ")"
Loop
End Sub
I thought I'd recommend a slightly different course of action, just to give you ideas :):
Sub macro()
Dim found As Range
Set found = Range("A:A").Find("*", after:=Range("A1"), searchdirection:=xlPrevious)
If Not found Is Nothing Then
Range(Range("A1"), found).Offset(0, 2).FormulaR1C1 = "=RC[-2]+RC[-1]"
End If
End Sub

Resources