vba vlookup keep formatting - excel

My code below has a vlookup which changes a cell in my data (CurrentMonth), but I can't get it to keep the formatting of the source. The return values in col 2 are 01, 02, 03 etc up to 12 in general text format, but the formula below returns 1, 2, 3 etc.
I've tried putting a ' before the numbers in the table I'm looking into, but that doesn't work. Also tried copying the format with code and then pastespecial formats on the changed value, but this doesn't work. The format type of the lookup table and the data I'm changing are identical. What code do I need to keep the formating please so I don't lose the 0 at the beginning, keeping the lookup value as text?
'vlookup based on combobox selection held in variable
Cat3No = Application.WorksheetFunction.VLookup(Me.ComboBoxCat3Name.Value, (Worksheets("ValidCombos").Range("C:D")), 2, False)
'variable used to change cell in dataset
Worksheets("CurrentMonth").Cells(Currentrow, 32).Value = Cat3No

If you don't need the values to be text, you could format the cells as a Custom format of Type "00":
EDIT
A simpler answer is to change your code to this:
'vlookup based on combobox selection held in variable
Cat3No = Application.WorksheetFunction.VLookup(Me.ComboBoxCat3Name.Value, (Worksheets("ValidCombos").Range("C:D")), 2, False)
'variable used to change cell in dataset
With Worksheets("CurrentMonth").Cells(Currentrow, 32)
.Value = Cat3No
.NumberFormat = "00"
End With

Related

Filtering for Multiple Colors in One Column in Excel

I've been having issues conditionally formatting a sheet 2 (Shipping Request List) that is mirroring select columns of sheet 1 (Master List).
-Starting in sheet 2 (Shipping Request List), column B, cell B2, has ='Master List'!D2 (from sheet 1) and continues down for hundreds of rows.
-The data in this field is mirroring cell 'Master List'!D2 (sheet 1) which could either be "Open" (or a number of other items based off a drop down list... no formulas). I'm only interested in what happens when the cell says, "Open".
-Cell D2 in sheet 1 has the following conditional formats based on D2 saying "Open" and a date in cell V2 in the Master List sheet.
=AND($V2<TODAY(),$D2="open") [turns purple]
=AND($V2-TODAY()>=0, $V2-TODAY()<=2,$D2="open") [turns red]
=AND($V2-TODAY()>=3, $V2-TODAY()<=4,$D2="open") [turns orange]
=AND($V2-TODAY()>=5, $V2-TODAY()<=7,$D2="open") [turns yellow]
When I try conditional formatting based on the values in sheet 2, i.e. by the value "Open" mirrored from sheet 1, the colors are not correct.
I tried various approaches.
Approach 1:
Change the conditional format equations in sheet 2 to reference the cell in sheet 1 instead of directly referencing the cells in sheet 2.
Approach 2:
Try using INDIRECT in the conditional format equations in sheet 2...but I'm not sure I did this correctly.
Approach 3:
Use a VBA code to create a UDF on sheet 1 to extract the color code of column D into an adjacent column (C), then filter by that number for the codes that represent purple, red, orange, and yellow.
(I am not at all good with VBA, but I can copy and paste a module and follow instructions.)
Function FindColor(n As Range) As Integer
FindColor = n.Interior.ColorIndex
End Function
In column C, C2 had =findcolor(D2) and then that got pulled down. This approach gave me numbers, but it gave me the same number for purple, blank, etc... extremely inconsistent.
Approach 4:
In new column C, add a formula to make the words either "purple", "red", "orange", or "yellow" appear based on the conditions mentioned in the conditional formatting formulas. I got only so far as the formula started getting a little too complicated for me to get through it. Only got this far (didn't even add orange and yellow yet) but the formula below is not returning "red" when the conditions call for it:
=IF(AND($V662<TODAY(),$D662="open"),"purple",IF(AND($V662-TODAY()>=0,$V662-TODAY()<=2,$V662="open"),"red",""))
I think I was getting close on the last approach, but I realize it's a lot of formula and will be added to 700+ rows, which will continue to grow.
As a slightly different approach: you could use a UDF to return the "color" for each row, and then run your conditional formatting rules based on the return values.
Put this in a regular module:
Function Classify(theDate, theStatus) As String
If theStatus = "open" Then 'check status
'If theStatus = "open" Or theStatus = "issue" Then
If Len(theDate) > 0 Then 'has a date?
Select Case theDate - Date
Case Is < 0: Classify = "purple"
Case Is >= 5: Classify = "yellow"
Case Is >= 3: Classify = "orange"
Case Is >= 0: Classify = "red"
End Select
End If
End If
End Function
In your worksheet you'd use (eg)
=Classify($V662, $D662)

Excel 2010 VBA: How to PasteSpecial a row to a range of rows and maintain row by row conditional formatting

Excel 2010:
This question relates specifically to the use of PasteSpecial with Conditional Formatting.
Overview:
I have a template row stored in a different sheet. This row contains roughly 350 columns and numerous formats, formulas and conditional formatting.
Data is loaded from SQL Server and contains N rows - generally between 400 and 15000.
The doing:
I copy the template row and insert require number rows:
AryVariant = rst_ADODB.GetRows
lRecordCount = UBound(AryVariant, 2) + 1
Templates.Range("TEMPLATE_ROW").Copy
sheet1.Range(sheet1.Range("Range_Start").Offset(1, 0), sheet1.Range("Range_Start").Offset(lRecordCount, 0)).EntireRow.Insert Shift:=xlDown
Copying from another sheet like this into a range makes a mess of the formulas, and conditional formatting, but copies the cell formats fine so i then go back over the range to update the formulas and conditional formatting:
Templates.Range("TEMPLATE_ROW").Copy
sheet1.Range(sheet1.Range("Range_Start").Offset(1, 0), sheet1.Range("Range_Start").Offset(lRecordCount, 0)).EntireRow.PasteSpecial xlPasteFormats
The issue:
While this works for formulas, it merges the rows in conditional formatting in the "Applies To" part while leaving the Formula in the rule referring to the top row in the range. Example (not sure how to show this part as i can't upload images):
Formula: "=$FB18"
Format: Some format here
Applies To: "=$D$18:$M$11436,$O$18:$AC$11436"
The desired result:
What i want is every row to be self contained, so:
Formula: "=$FB18"
Format: Some format here
Applies To: "=$D$18:$M$18,$O$18:$AC$18"
Formula: "=$FB19"
Format: Some format here
Applies To: "=$D$19:$M$19,$O$19:$AC$19"
The work around:
Currently I am applying the PasteSpecial row by row as a workaround:
For r = 0 To UBound(AryVariant, 2)
Templates.Range("TEMPLATE_ROW").Copy
sheet1.Range("sheet1_Dataset").Offset(r + 1, 0).EntireRow.PasteSpecial xlPasteFormats
Next r
While this works, it is appallingly slow with large data-sets.
Finally, the question:
Is there a way to get the desired result while applying the formats to the range as a whole?

Excel Match Numbers in 2 Columns to a Number in a 3rd

I've run into a bit of a road block. I get a .PDF output from an accounting program and copy/paste the data into excel, then convert text to columns. I am trying to match the GL code with the totals for that specific account. Columns A, B, and C show the state of my data prior to sorting it, and the lines under Intended Output show how I would like the data to output.
I am trying to automate this process, so I can paste data into columns A, B, & C in the raw format and have it automatically spit out the required numbers in the format of the Intended Output. The GL codes remain the same, but the numbers and the number of rows will change. I've color coded them for ease of review.
Thank you very much in advance!
Using a combination of the following formulas you can create a list of filtered results. It works on the principal that you Data1 text that you want to pull is the only text with a "-" in it, and that the totals you are pulling from Data2 and Data3 are the only numbers in the column. Any change to that pattern will most likely break the system. Note the formulas will not copy formatting.
IFERROR
INDEX
AGGREGATE
ROW
ISNUMBER
FIND
Lets assume the output will be place in a small table with E2 being the upper left data location.
In E2 use the following formula and copy down as needed:
=IFERROR(INDEX(A:A,AGGREGATE(15,6,ROW($A$1:$A$30)/ISNUMBER(FIND("-",$A$1:$A$30)),ROW(A1))),"")
In F2 use the following formula and copy to the right 1 column and down as needed:
=IFERROR(INDEX(B:B,AGGREGATE(15,6,ROW($A$1:$A$30)/ISNUMBER(B$1:B$30),ROW(A1))),"")
AGGREGATE performs array like calculations. As such, do not use full column references such as A:A in it as it can lead to excess calculations. Be sure to limit it to the range you are looking at.
Try this procedure:
Public Sub bruce_wayne()
'Assumptions
'1. Data spreadsheet will ALWAYS have the structure shown in the question
'2. The key word "Total" (or whatever else it might be) is otherwise NOT found
' anywhere else in the 1st data column
'3. output is written to the same sheet as the data
'4. As written, invoked when data sheet is the active sheet
'5. set the 1st 3 constants to the appropriate values
Const sData2ReadTopLeft = "A1" 'Top left cell of data to process
Const sData2WriteTopLeft = "J2" 'Top left cell of where to write output
Const sSearchText = "Total" 'Keyword for summary data
'*******************
Const sReplaceText = "Wakanda"
Dim r2Search As Range
Dim sAccountCode As String
Dim rSearchText As Range
Dim iRowsProcessed As Integer
Set r2Search = Range(sData2ReadTopLeft).EntireColumn
sAccountCode = Range(sData2ReadTopLeft).Offset(1, 0).Value
iRowsProcessed = 0
Do While Application.WorksheetFunction.CountIf(r2Search, sSearchText) > 0
Set rSearchText = r2Search.Find(sSearchText)
Range(sData2WriteTopLeft).Offset(iRowsProcessed, 0) = sAccountCode
Range(sData2WriteTopLeft).Offset(iRowsProcessed, 1) = rSearchText.Offset(0, 1).Value
Range(sData2WriteTopLeft).Offset(iRowsProcessed, 2) = rSearchText.Offset(0, 2).Value ' add this if there are more summary columns to return
'last two lines could be collapsed into a single line; at the expense of readability..
rSearchText.Value = sReplaceText 'so that next search will find the next instance of the trigger text
iRowsProcessed = iRowsProcessed + 1
sAccountCode = rSearchText.Offset(1, 0).Value
Loop
r2Search.Replace what:=sReplaceText, Replacement:=sSearchText
End Sub

Date value changes when copied

I have cells containing a simple concatenation function with D24 as the previous year (e.g. 15) and a custom format (MMM JJ)
CONCATENATE("Apr ",$D$24)
When I am copying and pasting these cells with a VBA then "Apr 15" becomes "15.04.16" and because of the formatting "Apr 16"
Selection.Value = Selection.Value
Was is the reason behind this? Is there another solution than just changing the format to text?
Excel will generally try to convert anything that looks like a date into a real date (serial number where 1 = 1 Jan 1900). One way to avoid that, and remove the formula as you are doing above, would be to pre-format as text. So:
With Selection
.NumberFormat = "#"
.Value = .Text
End With
might do what you want.
There are other ways, but if you don't change the cell format to text, or prefix the entry with a single quote ', any subsequent editing of that cell, even inadvertent selection, raises the risk of converting it to the real date.
That depends on what you want in your cell. Dou you want a string or a date?
If you want a string:
either format as text or
add a ': CONCATENATE("'Apr ",$D$24)
if you want a date:
use the following formula instead of concatenate: =DATE($D$24,4,1)
If you simply Copy Paste it, only the Value is pasted not the formatting (if I remember right)
Try to avoid using Selection instead use Range.
And use Range.Copy and Range.PasteSpecial Paste:=xlPasteFormats so your formatting is pasted with the values.

VBScipt to Excel - Range Function Syntax

re: Excel 2007
I'm using VBScript to create an Excel file and have a small issue with Syntax i think...
If i do this it happily pastes my chart from my application to a sheet in Excel at cell A1:-
ActiveDocument.GetSheetObject("CH_Contacts").CopyTableToClipboard True
XLSheet2.Paste XLSheet2.Range("A1")
What i now need to do is substitute variables instead of A1 but i'm unsure of the correct syntax to do this.
I have 2 variables called num_cols & num_rows so i want to do something like...
XLSheet2.Paste XLSheet2.Range(num_cols,num_rows)
I notice if i record an Excel macro and drag an area it produces this sort of thing...
Range("PV58:PZ58").Select
So do i need quotes somewhere as well ? Do i need the colon in there too with variables?
Any help appreciated
Assuming num_cols and num_rows are Long/Integer data type representing the column/row number (i.e., Column A == 1, Row 16 == 16, etc.), then use the Cells property:
XLSheet2.Paste XLSheet2.Cells(num_rows, num_cols)
The Cells property returns the range at the specified index of row number/column number, so:
Cells(1,1) '## Range("A1") -- Row 1, Column 1
Cells(13, 5) '## Range("E13") -- Row 13, column 5
Etc.
So do i need quotes somewhere as well ? Do i need the colon in there too with variables?
No, only if you are trying to build a literal address string, like "A6:A13", and even then it's not strictly necessary and the range can usually be constructed with another method like Resize or Offset.

Resources