Adding "0" value to blank values while importing data - excel

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

Related

Excel VBA Sort when Inputting Data, Updated in All Other Sheet?

I am new to VBA Excel.
I wanna create a database for each month, with 1 'Main Sheet' for the list of names, and the list on 'Main Sheet' will sort automatically as a row when I entered data along with the update of the other sheet.
I found this code, and it's only updated/sorting in the sheet entered (let's say the 'Main Sheet'). Is that possible if the entered data and sorting updated automatically in all other sheets?
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
If Target.Column = 1 Then
Dim lastRow As Long
lastRow = Cells(Rows.Count, 1).End(xlUp).Row
Range("A2:BN2" & lastRow).Sort key1:=Range("A2:A" & lastRow), order1:=xlAscending, Header:=xlNo
End If
End Sub
I tried referencing/paste the link to the name for each month (start from A2), but I have no idea to keep the column beside A2 (B2, C2, etc) sticking with the A2 as a full row.
Thanks!
Look at this part of your code for ideas how to solve your problem.
Range("A2:BN2" & lastRow).Sort Key1:=Range("A2:A" & lastRow)
The instruction is to sort Range("A2:BN2" & lastRow) on Key1. The range to sort starts at A2 and ends with the last used row in column BN. All columns of all rows are included, as they should. But lastRow was determined in column 1, which is column A. We hope that all columns have the same length. Observe that we don't know on which tab the range is located. By default, if no sheet is specified, Excel will presume the ActiveSheet. This is borne out by the fact that the code is located in a worksheet event procedure. Of course, this code is linked to the sheet on whose code module it is placed. It won't run when another sheet is active.
However, the syntax for specifying a range for a particular sheet would look like this.
With Worksheets("MySheet")
lastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
Set MyRange = .Range("A2:BN2" & lastRow)
End With
Please observe all the leading periods, each of which links the statement it precedes to the worksheet specified in the With statement. Imagine a loop in which the sheet name is changed on each turn, thereby defining the same range on a different sheet on each instance.
The Key argument of the Sort method specified the column on which to sort. It's called "Key" instead of "Column" because there are sheet columns and range columns. In your case the sheet rows are different from your range rows because your range starts in row 2 but the range columns are identical with the sheet columns. Anyway, Key1:=Range("A2:A" & lastRow) isn't a very good pointer to the column you want to sort on. 1 single cell would suffice, like Key1:=Range("A2") - or Key1:=Cells(2, 1) as I would prefer.
As you see, this part is a lot simpler. The only important point to observe is that the cell specifying the Key must be within the range to be sorted. This also means that you can't specify a Key on the ActiveSheet for a sort range on another tab. When you construct your loop, therefore, you will need to take a cell from the properly defined sort range as Key.

.PasteSpecial Paste:=xlPasteColumnWidths works partially only with the last page

I wrote a script to copy sheet by sheet from ThisWorkbook to another workbook. Everything seems to work fine except for the column width of the last sheet, and only the last sheet. Some columns have wrapped text which is not found in the original. I eliminated most of the code and only copied formats and column widths. Still, the column widths are different from that in the original file. And this only happens with the last sheet.
Sub copy_all()
Dim rng As Range
Dim i As Integer
Dim destBook As Workbook
Set destBook = Workbooks("Book3")
With destBook
For i = 1 To ThisWorkbook.Sheets.Count
Set rng = ThisWorkbook.Sheets(i).UsedRange
rng.Copy
.Sheets(i).Range("A1").PasteSpecial Paste:=xlPasteFormats
.Sheets(i).Range("A1").PasteSpecial Paste:=xlPasteColumnWidths
Next i
End With
End Sub
I even wrote a script to list the column widths of the original and copied files so it'd easy to compare. Indeed, only the last page of the column widths are different. All the other 13 pairs of pages of the original and copied files have the identical column widths.
As you can see from the following picture, only some of the column width on the last page are different from the original, not every one of them. Some are identical to the original. Only those with a width of 87 are copied to becoming a width of 48.
My question is what is wrong with the copy script? Thanks in advance for any help.

Excel VBA copy filtered CurrentRegion visible cells but exclude last 3 columns

Having a small issue. I have a large piece of code that takes a reference number selected by the user and locates corresponding rows (there can be multiple rows or none to locate) on multiple other sheets by filtering and then copying the data.
This works well except it copies all visible data (columns A-N) when I really want it to copy columns A to K (as L to N on the paste sheet is where I have formulas that set reference numbers and therefore can't be pasted over).
I have tried a couple of changes to the below section of code including offset however it either ignores the offset (probably because I'm using xlCellTypeVisible which I had to do as the data that needs to be copied can be across multiple non sequential rows) or I get an error about selection method not supported.
Any thoughts?
sheet that is being copied - DbExtract
Sheet that data is pasted to - DuplicateRecords
Thanks.
Sub UpdateInputWithExisting()
' Other code that works using set with values and active cell offset with values for other sheets
Sheets("TK_Register").Range("A1").CurrentRegion.AutoFilter field:=12, Criteria1:=RefID
Dim DbExtract, DuplicateRecords As Worksheet
Set DbExtract = ThisWorkbook.Sheets("TK_Register")
Set DuplicateRecords = ThisWorkbook.Sheets("EditEx")
DbExtract.Range("A1").CurrentRegion.SpecialCells(xlCellTypeVisible).copy
DuplicateRecords.Cells(31, 3).PasteSpecial xlPasteValues
On Error Resume Next
Sheets("TK_Register").ShowAllData
On Error GoTo 0
ActiveWorkbook.RefreshAll
Sheets("EditEx").Select
ActiveWindow.SmallScroll Down:=-120
Range("B14:M14").Select
MsgBox ("Record Retrieved. Make your changes and ensure you click 'Save Changes' to update the Master Registers")
End Sub
Need to use .Resize method. Replace this line:
DbExtract.Range("A1").CurrentRegion.SpecialCells(xlCellTypeVisible).copy
With this:
With DbExtract.Range("A1").CurrentRegion
.Resize(, .Columns.Count - 3).SpecialCells(xlCellTypeVisible).Copy
End With

VBA to paste from one column to another?

I need code for the below requirement, wherein the below code is not working:
Sub sample48()
Worksheets("Sheet").Select
Range("AG1").Select
Range("A1:AQ1").Autofilter Field:=33, Criteria1:="COD*"
Range("AG:AG").Value = Range("AM:AM").Value
End Sub
I need to filter a word called **COD** in column AG, and then I need to copy and paste values from Column AG to Column AM only for the those filtered line items.
Note that in excel you can copy from filtered area, but when you are pasting, data will not paste on filtered(visible) cells, instead pasted continuously. There is 2 way to do your task:
1: Use loop
Sub MyCopyPaste()
Dim RngCnt As Range
Dim LastRow As Long
LastRow = Range("AM" & Rows.Count).End(xlUp).Row
For Each RngCnt In Range("AM1:AM" & LastRow).SpecialCells(xlCellTypeVisible)
Range("AG" & RngCnt.Row).Value = Range("AM" & RngCnt.Row).Value
Next
End Sub
2: Without Loop
If in some case you don't want use loop or vba, you should create another column and put an ID number into it. This column will used to sort the worksheet to retain rows order to original. Then create another column with name custom_Order and after filtering, put numbers into it, then show all data and sort worksheet based on custom_order and then filter it. In this case all your expected rows will be filter and come continuously and you can easily copy and paste.
Sub sample48()
Range("A1:AQ1").AutoFilter Field:=33, Criteria1:="COD*"
Range("AG:AG").Copy
Range("AM:AM").PasteSpecial
End Sub
This does quite literaly what you asked:
filter your range
copy colmun AG (because it is filtered, only filtered values are copied)
paste filtered values in AM
you can not use an equation on a range for an entire range. Also, judging by your description, I assume your equation had to be the other way around.

VBA paste range with dynamic selection

I read multiple Q&A's, however it's difficult for me to really understand all the long scripts with the usage of different objects.
I am trying to select a range from one worksheet to an other.
I want to keep the range dynamic, because the range can vary every time. By doing so I have used the following script:
Dim range As Long
For range = ActiveCell To ActiveCell.End(xlDown)
Sheets("Stock Report").range("A4" & range).Value =
Sheets("Unique File").range("Y8" & range).Value
However it doesn't do anything.
This script does work, but I would like to keep the last cell dynamic:
Sheets("Stock Report").Range("A4:A9000").Value =
Sheets("Unique File").Range("Y8:Y90004").Value
I have to do this for multiple columns which are calculated by using other files in a different worksheets and need to sort them finally without all the calculations in an other one.
Any suggestions?
OK try.
Sheets("Unique File").Range("Y8:Y" & Sheets("Unique File").Range("A4").End(xlDown).Row + 4).Copy
Sheets("Stock Report").Range("A4").PasteSpecial Paste:=xlPasteValues
Range("A4").End(xlDown).Row gets the last row of the data on the Stock Report sheet and is used to copy down to the same row on the Unique File sheet. I added 4 because your range starts on 8 on the Unique File sheet.
I think your code didn't work because you were trying to use the "range" you created from the Stock Report sheet on the Unique values sheet.

Resources