VBA: Loop Running - Not Throwing Error. Not Performing - excel

Hope you're all well. I am in the process of working through an excel sheet that has 132 rows of data. In Column H of that data I have cells of comma separated values, that contain a list of countries. The problem with the list of countries is that I keep receiving it in a non-standardized format. I am attempting to standardize it now. With some help, I have written a VBA macro that is supposed to loop through column H, with the standardized values, and their non-standardized values in a separate sheet, Sheets(4). In Column A of Sheets4, I have the non-standardized value, in column B of Sheets(4) I have the standardized values, which I desire to be brought over and then replaced for the various non-standardized values in column A.
When I run the macro however, it appears as if it is not running at all. It takes about 5 minutes to run, and when it's done, none of the changes have occurred. Here are some of the things I have tried to make sure that none of the obvious things are at work with the macro:
I have tried to deliberately insert the exact error text I have in Column A of Sheets(4) of Sheets4, so that it will automatically pick up on the text, as they are the exact image and mirror of eachother.
I have gone into the "Views", "Local Window" and followed the variable step by step after running through the code step by step to make sure that I am actually following the proper procedure and that in each case it is picking up and detecting the the different errors in each case.
tried turning on and off the computer.
Does anyone have any thoughts on what I should do in order to get this Macro running?
Sub Translate_Country_Name()
'Variable Names
Dim Ary As Variant
Dim i As Long
With Sheets(4)
Ary = .Range("A2", .Range("B" & Rows.Count).End(xlUp))
End With
With Sheets(1).Range("H:H")
For i = 1 To UBound(Ary)
.Replace Chr(160), " ", xlPart, , , , False, False
.Replace Ary(i, 1), Ary(i, 2), xlPart, , True, , False, False
Next i
End With
End Sub

Related

Unwanted change when using "TextToColumns" twice

I have the following issue.
One of my sheets holds a column that contains values stored as text (e.g. value as 1,22 stored as a text). Currently I use the following Code to convert those entries to values:
Sub Convert()
Range(Cells(2, "K"), Cells(Rows.Count, "K").End(xlUp)).TextToColumns DataType:=xlFixedWidth, DecimalSeparator:=","
End Sub
If I run the macro once the result is fine. However if I run to macro a second time (after I already converted the text to values with the code shown above). The numbers change their format from the comma "," as the decimal separator to a dot "." as a decimal separator (e.g. 1,22 --> 1.22).
This is a problem, because my region uses the comma.
Does anybody know how to prevent this from happening?
Kind regards
Sombrero
Here Screenshots:
Original data#
After first time text2columns:
After second time text2columns:
You original data are strings, and running TextToColumns converts them into numbers. When you run TextToColumns a second time, Excel needs to convert those numbers first into strings.
I can only guess about the internal logic of this conversion, but it wouldn't surprise me if this is not using any regional settings.
Anyhow, I would say it's not a good idea to use the TextToColumns command on numeric values. Use a filter to get only the cells containing text:
Dim r As Range
set r = Range(Cells(2, "K"), Cells(Rows.Count, "K").End(xlUp))
On Error Resume Next ' To prevent runtime error "No cells found"
Set r = r.SpecialCells(xlCellTypeConstants, xlTextValues)
If err.Number = 1004 then exit sub
On Error Goto 0
r.TextToColumns DataType:=xlFixedWidth, DecimalSeparator:=","

Adding "0" value to blank values while importing data

I have an Excel workbook with multiple sheets, which are fed by data imported from multiple external excel files. To complete this action, I successfully built VBA code that allows the user to open the files.
Behind the scenes, one of the subs imports data from the General Ledger raw data into a spreadsheet with multiple columns. I am attaching a couple screen grabs here to show what is happening:
The pre-existing data looks like this:
Raw data once downloads will look like this:
Once the macro runs, the previous columns populate as intended, but because the last two columns are populated intermittently, they end up doing this:
I only summarized columns in these images, as the workbook has 28 columns preceding the two columns.
Due to the size of the data and the macro itself, I would like to maintain the structure of the code. Especially since it is intended that this macro be transferred to other general ledger workbooks.
My macro looks like this (summarized for time):
1. Sub Import_GL1001
2. Dim FileToOpen As Variant
3. Dim OpenBook As Workbook
4. Application.ScreenUpdating = False
5. FileToOpen=Application.GetOpenFileName(Title="Import_GL1001",FileFilter:="ExcelFiles (*xlsx*),*xlsx*")
6. If FileToOpen<> False Then
7. Set OpenBook=Application.Workbooks.Open(FileToOpen)
8. OpenBook.Sheets(1).Range("$A$2:$A$1500").Copy
9. ThisWorkbook.Worksheets("GL 1001.10").Range("A"&Rows.Count).End(xlUp).Offset(1,0).PasteSpecial xlPasteValues
10. OpenBook.Sheets(1).Range("$B$2:$B$1500").Copy
11. ThisWorkbook.Worksheets("GL 1001.10").Range("B"&Rows.Count).End(xlUp).Offset(1,0).PasteSpecialxlPasteValues
12. ......
13. OpenBook.Sheets(1).Range("$AC$2:AC$1500").Copy
14. ThisWorkbook.Worksheets("GL 1001.10").Range("AD"&Rows.Count).End(xlUp).Offset(1,0).PasteSpecial xlPastevalues
15. OpenBook.Sheets(1).Range("$AD$2:$AD$1500").Copy
15. ThisWorkbook.Worksheets("GL 1001.10").Range("AF"&Rows.Count).End(xlUp).Offset(1,0).PasteSpecialxlPasteValues
In an ideal world, the values would copy and paste as is, blanks and all, so when the macro is run in the future the two columns in question do not change position based on the last blank cell. I tried multiple methods and variations, but the only logical thing I could think of is if I manage to find a way to insert a "0" into each cell that is blank every time the data is imported, without changing all the blank cells (i.e. if we only have 30 rows of data, I don't want all of the blank cells in AF:AF to be "0"). If the cells have a value at all, then that means that the macro itself won't have to be dramatically retooled.
Please, try the next way:
The last row where to paste the values should be calculated only once, based on a column you know that it is all the time filled with values.
Dim lastERow As Long, sh As Worksheet
Set sh = ThisWorkbook.Worksheets("GL 1001.10")
lastERow = sh.Range("A" & sh.Rows.Count).End(xlUp).Offset(1,0).row 'last empty row
Then use this reference for all the columns where you intend pasting starting from the same empty cell row:
'your existing code
OpenBook.Sheets(1).Range("$A$2:$A$1500").Copy
sh.Range("A" & lastERow).PasteSpecial xlPasteValues
'...
'...
OpenBook.Sheets(1).Range("$AC$2:AC$1500").Copy
sh.Range("AD" & lastERow).PasteSpecial xlPastevalues
OpenBook.Sheets(1).Range("$AD$2:$AD$1500").Copy
sh.Range("AF" & lastERow).PasteSpecial xlPastevalues
In this way, the code will paste starting from the same empty row, in all columns.
If you want following your way of solving, please run the next code, but after your existing code runs. It will take the reference from the last filled cell of the A:A column:
Sub ZeroInEmptyCells()
Dim sh As Worksheet, lastRow As Long, rngEmpt As Range
Set sh = ThisWorkbook.Worksheets("GL 1001.10")
lastRow = sh.Range("A" & sh.rows.count).End(xlUp).row 'last row in column A:A
On Error Resume Next 'if no empty cells, the next code line will return an error (without this line...):
Set rngEmpt = Union(sh.Range("AD1:AD" & lastRow), sh.Range("AF1:AF" & lastRow)).SpecialCells(xlCellTypeBlanks)
On Error GoTo 0
If Not rngEmpt Is Nothing Then rngEmpt.value = 0
End Sub

Replace periods with commas ends up with period deletion

This is my first month with VBA and I've overcome so many obstacles and reduced walls of code with loops, made code pretty much uncrashable, even when user using macro doesn't know what he/she is doing, but I am stuck with this:
If i = 1 Or i = 2 Then
Columns("F:F").Select
Selection.Replace ".", ","
Selection.NumberFormat = "dd\/mm\/yyyy hh:mm:ss"
End If
For some reason the result of replacement of:
438595.73402778 is this 43859573402778
I tried different variations from recording the macro to gradually simplifying the code and ended up with above. Always same result. What am I missing here?
The code is kind of complex, because I have to take data from 6 temporary workbooks into 4 sheets, secure it, depending on user login etc. It works great, but I thought, let's make it even better, because 3 out of those 6 qlikview workbooks have incorrect format in 1 of 4 time tracking columns.
It's kind of sad that I had to write my first post for such thing
I assume your current data is actually string data looking like numeric values. If column F is formatted to General and these "string" numbers appear, then you could change that around using Range.TextToColumns. For example:
Sub Test()
Dim lr As Long, rng As Range
With Sheet1
'Get last used row of column F and set rng
lr = .Cells(.Rows.Count, 6).End(xlUp).Row
Set rng = .Range("F2:F" & lr)
'Replace dot with comma and change to numeric
rng.TextToColumns Destination:=Range("F2"), DataType:=xlFixedWidth, DecimalSeparator:=".", ThousandsSeparator:=","
rng.NumberFormat = "dd\/mm\/yyyy hh:mm:ss"
End With
End Sub
Seems like you have different decimal separator settings in Excel files.
Go to Options-> extended-> use systems decimal separator.
This option may be off on some workbooks and ,is set as decimal separator.
to fix:
If Application.International(xlDecimalSeparator) = "," Then
MsgBox "Wrong decimal separator(,)!!"
Application.UseSystemSeparators = True
End If
If you want to output dot but leave comma the separator use
With ThisWorkBook.WorkSheet("Sheet1")
MsgBox Str( .Range("A1"))
End With
See Using VBA to detect which decimal sign the computer is using

Trying to Remove Duplicates based on first column

I am currently trying to remove rows from column A to column V based on duplicates found in column A.
my current formula is:
Workbooks(TgtWB).ActiveSheet.Range("A15:V500").RemoveDuplicates _
Columns:=Array(1), Header:=xlYes
My header is located on row 15.
the error i am getting is
Application-defined or object-defined error
I have tried switching ActiveSheet with worksheet("xxx") but still doesn't seem to work either. i'm not sure what i'm doing wrong here.
Try (note worksheetS, not worksheet),
Workbooks(TgtWB).worksheetS("xxx").Range("A15:V500").RemoveDuplicates Columns:=1, Header:=xlYes
'or,
ActiveSheet.Range("A15:V500").RemoveDuplicates Columns:=1, Header:=xlYes
If TgtWB is open, it may or may not contain the ActiveSheet. Each open workbook does not have an ActiveSheet. There is only one ActiveSheet for the application instance. ActiveSheet is not a property of the Workbooks collection.
Using built in functionality is great, unless you're a beginner like myself and the .Applications and .Worksheets get overwhelming and confusing. For a small data set, such as columns A through V (depending obviously on how many rows you have), a loop and if-statement not only can work well, but can be good practice as well! Something like this may work well:
Dim CurrentValue, LastValue As Variant
LastValue = ""
For I = 1 To 500
CurrentValue = Sheets("Sheet 1").Range("A" & i).Value
If CurrentValue = LastValue Then
Sheets("Sheet 1").Range("A" & i & ":V" & i).Clear Contents
Else
LastValue = CurrentValue
End If
Next i
This will loop through every row, ask if the current value in the cell is the same as the one previously observed (except the first one, the first one will automatically be saved by nature), and if it has been, it will clear the contents of the row. If it's not the same, it will assign it to the new variable and begin looking for new ones.
There are two drawbacks with this method that can be solved by simply adapting the code to your needs:
Non-Sequential Items: If the values that are duplicates are not sequential, the code won't kick them out. At that point I recommend using an application code or a dictionary. Dictionaries are infinitely useful for storing unique data entries and skipping duplicates.
Deleting Rows: When you delete rows in a loop it messes up your loop, throwing off the order of your incrementer. The best way to combat this is by first clearing the columns then having your code loop for empty rows and delete them outside of your loop.
This is very basic but something I've found greatly helpful as a beginner and hopefully other beginners and yourself can learn something from it.
Happy Coding!

Searching data from one spreadsheet into another

I'm making a macro that is supposed to check for a set of values in an input list from the user. If the values from my source list are NOT in the user input, they have to be copied into a different spreadsheet. The macro runs without errors, but it won't filter any results. It just copies everything.
This is the code:
Sub CheckRow()
For i = 2 To Application.CountA(Worksheets("Source").Range("A:A")) 'Loop through rows
Set rgFound = Worksheets("Input").Range("A:A").Find(Worksheets("Source").Range("A" & i).Value, LookAt:=xlWhole) 'Find the value from the source list in the Input List
If rgFound Is Nothing Then 'If there is no match it goes to output
Worksheets("Output").Range("A" & Application.CountA(Worksheets("Output").Range("A:A")) + 1).Value = Worksheets("Source").Range("A" & i).Value 'Copy the value beow any existing values
End If
Next i
End Sub
I will appreciate any suggestions you have to offer.
Your condition should be If Not rgFound Is Nothing Then (the Not is missing in your code). Basically, the Find method doesn't find anything and therefore everything is copied.
I also advise you to use Option Explicit at the top of your code sheet. This would alert you to the use of the variable j in Find(Worksheets("Source").Range("A" & j). I think you are looking for A & i. However, since j appears to have a value of 0 your code shouldn't copy anything because there is no row 0. Using Option Explicit would force you to declare all variables, eliminating guessing games like this one when reading your code. Since you are the one to read it most of the time you would also be the prime beneficiary of the improvement.
Fixed. It seems that the Find method thinks that Value and ="Value" are two different things. Once I changed all the formula cells to plain text my code worked like a charm.

Resources