Formatting cells to numbers in vba - excel

I'm currently exporting a document (wsCopy) from a software and paste special valuing the data to another excel workbook I'm creating (wsDest). Within (wsDest), I also have two vlookups, columns AI:AJ, which reference the newly created exported data, a "SupportReference" tab, and a "RegionLookup" tab. My issue is that the values in the exported data is formatted weirdly. Even though the exported data format says "General", the vlookups in column AJ are returning #N/A errors. The only ways to fix this problem is if I click on the referenced cells (column AH), which includes the exported data, hit F2, then Enter, or create a vba that will multiply all of the vlookups in column AI by 1. However, I don't want to do the first option since I'll have to do it for ~14000 rows. The issue with the second option is that, multiplying the entire AI column by 1 won't work if the vlookup in column AI returns with any letter; also, it gets rid of the vlookup in column AI. Below is what I came up with:
Sub CopyOver()
Dim wsCopy As Worksheet
Dim wsDest As Worksheet
Dim lCopyLastRow As Long
Dim lDestLastRow As Long
Set wsCopy = Workbooks("Export").Worksheets("Sheet1")
Set wsDest = ThisWorkbook.Worksheets("Data")
'1. Find last used row in the copy range based on data in column A
lCopyLastRow = wsCopy.Cells(wsCopy.Rows.Count, "A").End(xlUp).Row
'2. Find first blank row in the destination range based on data in column A
'Offset property moves down 1 row
lDestLastRow = wsDest.Cells(wsDest.Rows.Count, "A").End(xlUp).Offset(1).Row
'3. Clear contents of existing data range
wsDest.Range("A9:AH" & lDestLastRow).ClearContents
'4. Copy & Paste Data
wsCopy.Range("A2:AH" & lCopyLastRow).SpecialCells(xlCellTypeVisible).Copy
wsDest.Range("A9").PasteSpecial Paste:=xlPasteValues
'Start copy down formulas
Dim DestLastPopulatedRow As Long
'Find last populated row
DestLastPopulatedRow = wsDest.Range("A" & Rows.Count).End(xlUp).Row
'Select the rows where formula is to be populated
wsDest.Range("AI9: " & "AJ" & DestLastPopulatedRow).FillDown
End Sub
The very last part of the code (wsDest.Range("AI9: " & "AJ" & DestLastPopulatedRow).FillDown) is where I start having issues because the vlookup formula starts in cell AI9. The vlookup formula is as follows:
Column AI Vlookup:
=VLOOKUP(AH9,'SupportReference'!E:E,1,FALSE)
Column AJ Vlookup:
=VLOOKUP(AI9,'RegionLookup'!M:M,1,FALSE)
Attempted VBA code multiplying column AI:
With wsDest.Range("AI9: " & "AI" & DestLastPopulatedRow)
.Value = Evaluate(.Address & "*1")
End With
Let me know if you need more clarification or further data.
Thank you.

If you don't need the VLOOKUP functions to be active, which I expect to be the case because you are copying a large block of data in, you can use VBA to set the value of the lookup cells instead of a function. Here's a sub-procedure where you pass it a destination cell and other lookup parameters, and the VBA finds the value and puts it in the destination cell:
Sub exact_lookup(destination As Range, lookup_value As Variant, lookup_table As Range, column As Integer)
Dim foundCell As Range
Set foundCell = lookup_table.Columns(1).Find(lookup_value, , , xlWhole)
If foundCell Is Nothing Then
destination.Value = CVErr(xlErrNA)
Else
destination.Value = foundCell.Offset(0, column - 1).Value
End If
End Sub
Then write a loop to fill the value of each cell where your current approach uses lookup formulas. An example call is:
exact_lookup wsDest.range("AI9"), wsDest.range("AH9").value, worksheets("RegionLookup").range("E:E"), 1
Note: I'm not entirely sure I understand just what you doing, but hopefully this approach will work this is enough to get headed in the right direction.

Related

Trying to reference and pull all cells that have a blank in another column

I am brand new to VBA as a disclaimer.
I have data I am inputting into one sheet (Emptys) and am trying to grab a cell from another sheet (report) in the same row that has a blank in a certain column.
For example:
Sample Report
I am trying to pull the value from the column A if the cell in the same row of column M is empty and reference that to a different sheet.
I am also trying to skip any rows that have a value in them and only pull the data from the rows that have a blank in column M.
I have tried a few things and I am in a bit over my head.
All that I have gotten to work is this basic formula:
=IF( Report!M2= "",Report!A2, "" )
I still have to sort out empties manually this way.
I feel like I was on the right track here but not sure where I went wrong:
Dim myrange
Dim id
myrange = Sheets("Report").Range("M2:M")
id = Sheets("Empty_Slots").Range("A2:A")
For Each cell In myrange
If IsEmpty(cell) Then
id = Sheets("Report").Range("A2:A")
End If
Next cell
Any help and explanation would be greatly appreciated!
You may access row numbers of those blank cells and use them in worksheet 2:
Sub Macro1()
Dim wk1 As Worksheet
Dim wk2 As Worksheet
Dim LR As Long
Dim rng As Range
Set wk1 = Worksheets("Sheet1")
Set wk2 = Worksheets("Sheet2")
With wk1
LR = .Range("A" & .Rows.Count).End(xlUp).Row 'last non blank cell in column a
For Each rng In .Range("M2:M" & LR).SpecialCells(xlCellTypeBlanks) 'array of blank cells in column M
wk2.Range("A" & rng.Row).Interior.Color = vbYellow 'do something with column A from worksheet2 based on row numbers from column M in worksheet 1
Next rng
End With
Set wk1 = Nothing
Set wk2 = Nothing
End Sub
The code loops trough each blank cell in column M from Sheet1 and pulls the row number. Then in worksheet 2 it uses that row number in column A.
After executing code, I've colored cells in sheet2 but based on sheet1

How To Copy Range of Last Row of Data and Paste into Row below It

I am trying to to create a macro to get the last row of data on my sheet & copy/paste it into the row before it.
I need it to pick up the data in Columns B-N.
I am able to do it for just column B using the below code but i cant figure out the syntax to get it do do it for column B-N - can someone help?
Sub copylastrow()
Worksheets("Sheet1").Activate
Range("B" & Rows.Count).End(xlUp).Copy
Range("B" & Rows.Count).End(xlUp).Offset(1).PasteSpecial
End Sub
Some comments in the code:
Define the source sheet (no need to activate it)
Find the last row in an specific column
Set the source range according to columns and last row
Transfer values without copying them is faster
Assumptions:
Column B is the reference to get the last row
You're just pasting values
Read the comments and adjust the code to fit your needs.
Code
Public Sub CopyLastRow()
' Define the source sheet (no need to activate it)
Dim sourceSheet As Worksheet
Set sourceSheet = ThisWorkbook.Worksheets("Sheet1")
' Find the last row in an specific column
Dim lastRow As Long
lastRow = sourceSheet.Range("B" & sourceSheet.Rows.Count).End(xlUp).Row
' Set the source range according to columns and last row
Dim sourceRange As Range
Set sourceRange = sourceSheet.Range("B" & lastRow & ":N" & lastRow)
' Transfer values without copying them is faster
sourceRange.Offset(1).Value = sourceRange.Value
End Sub
Let me know if it works

Copy data to sheet named in column header and cell named at beginning of row, then loop

I have some production data in a table on my Source worksheet. In the header of each column is the name of the Destination worksheet, where the data in that column is to be pasted. In Column A at the beginning of each row is the destination column on the destination worksheet; and in Column B is the destination row. Column C concatenates the two to display the cell name, e.g, T138, which would be the destination cell on the destination worksheets. I haven't been a member long enough to embed an image in this post, but there is an pic of the table here:
So each datum on the Source worksheet is to be copied and then pasted to the worksheet named in the column header and the cell named in column C at the beginning of the row (or alternatively, in the column named in Col.A and the row named in Col.B) Then the script should loop back through the rest of the data cells and do the same for each of them: copy data, paste to sheet specified in column header and cell specified at the beginning of the row in Col.C.
Even though I am a total beginner, I actually thought this would be a fairly simple matter. But I haven't been able to figure out how to do this. I've tried various scripts, but none of them even began to do the job, and they really aren't even worth displaying here. I was hoping someone could point me in the right direction. Worse yet, none of my extensive searches have turned up anything like what I want to do. Maybe I just haven't used the right search terms. "Variable" seems to have gotten the closest to useable search results, but not exactly.
Here is an image of what one of the destination sheets looks like, in relevant part:
Here's a better image:
This code will Loop over each cell in the range of G3 to J and LastRow. Copying the cell if it's numeric to the sheet based on the column header and the cell from column C.
Public Sub MoveData()
Dim rcell As Range, rng As Range
LastRow = ActiveSheet.UsedRange.Rows.Count + ActiveSheet.UsedRange.Rows(1).Row - 1
'MsgBox LastRow
Set rng = Application.ActiveSheet.Range("G3:J" & LastRow)
For Each rcell In rng.Cells
If Not Len(rcell.Value) = 0 Then
'MsgBox rcell.Value
Header = rcell.Offset(1 - rcell.Row).Value
'MsgBox Header
Set DestSheet = ThisWorkbook.Sheets(Header)
Set DestCell = ActiveSheet.Range("C" & rcell.Row)
'MsgBox DestCell
Application.ActiveSheet.Range(rcell.Address).Copy Destination:=Sheets(Header).Range(DestCell)
End If
Next rcell
End Sub

Inserting a column & text within new cells (VBA)

I am using Excel 2013, trying to insert a new column at the start of my sheet (Column A) & then insert text into the newly created cells. I would like to insert the word "OR" into every new cell created from row 1 all the way down to the last row that contains data within my sheet. The amount of rows in the sheet will change daily so ideally I would like the code to auto detect the amount of rows if possible rather than the code having to be changed daily.
I have searched for the answer on here & can find how to insert a new column or text but I can't find the specific code required for my above issue.
Any help would greatly be appreciated please
How about the following, it will count the number of rows in Column A, then insert a new Column and enter "OR" on each cell from Row 2 to Last:
Sub foo()
Dim rng As Range
Dim ws As Worksheet: Set ws = Sheets("Sheet1")
'declare and set your worksheet, amend as required
LastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
'get the last row with data on Column A
ws.Columns("A:A").Insert Shift:=xlToRight
'insert new column A
Set rng = ws.Range("A2:A" & LastRow)
'set range from A2 to Last, amend if your data has no headers and you want to insert "OR" into A1 too.
rng.Value = "OR"
'add the value "OR" to each cell
End Sub

Excel VBA Vlookup issue

I'm a complete beginner to Excel VBA.
The following is code I've written that should iterate through a column in a sheet, filling values by referring to the column value to it's left and referring to another sheet in the same workbook to find what the correct corresponding value should be.
I've used a While loop so i can apply this VLOOKUP macro to each cell in the column ( only the lookup value, changes, which should be a variable denoting the column to the left) :
Dim result As String
Dim sheet As Worksheet
Dim rownum As Integer
Dim iterator As Integer
Dim lookup_value As String
Dim vlookupString1 As String
Set sheet = ActiveWorkbook.Sheets("datasheet")
rownum = sheet.Range("A1").End(xlDown).Row
Set iterator = 3
While iterator < rownum
lookup = "M" & iterator
vlookup1String = "=VLOOKUP(" & lookup & ",'GICS Sub-industry codes'!$A$2:$B$155,2,FALSE)"
With ActiveSheet.Cells
Range("N" & iterator).Select
Selection.Value = vlookup1String
End With
iterator = iterator + 1
End While
I'm getting an error # end while saying "expected if or select or sub..."
1) Have i made a syntax error?
2) Is my approach correct. I have observed this string approach to designing VLOOKUPS in vba only in one other place. It seemed best suited.
Fixing your code
You should use Wend not End While for your loop.
Cleaner Alternative
But you can fill an entire range in a single shot as below
It is better to "loop up" a range from the bottom using End(xlup) than to look down with End(xlDown) (which relies on no spaces)
You almost never need to use Select in VBA
Further explanation
rng1 sets a working range from the last used cell in column A in sheet datasheet to A3
rng1.Offset(0, Range("N1").Column - 1) says offset rng1 (which is column A) by 13 columns to use column N (ie OFFSET A by 14-1) for the formula insertion
I used the macro recorder to get the code you needed in column N for this part "=VLOOKUP(RC[-1],'GICS Sub-industry codes'!R2C1:R155C2,2,FALSE)".
IN R1C1 speak, RC[-1] means refer to the cell in the same row, but one column to the left. So in N3, the formula will start as =VLOOKUP(M4..), So in N30, the formula will start as `=VLOOKUP(M30..) etc
Suggested code
Sub QuickFill()
Dim ws As Worksheet
Dim rng1 As Range
Set ws = Sheets("datasheet")
Set rng1 = ws.Range(ws.[a3], ws.Cells(Rows.Count, "A").End(xlUp))
rng1.Offset(0, Range("N1").Column - 1).FormulaR1C1 = "=VLOOKUP(RC[-1],'GICS Sub-industry codes'!R2C1:R155C2,2,FALSE)"
End Sub

Resources