Using a dictionary to store & read values to change cell color and call macro - vba

I have a form on a sheet (Sheet2), I would like for the values entered in the D column cells to be compared to a list of values on a different sheet (Sheet5, column C). If the value entered in the D column of Sheet2 equals any of the values in Sheet5 column C, I want the F column cell in the same row of Sheet2 to turn red. If D7 = a value in column C of Sheet5, I'd like F7 to turn red. Ultimately I want this to check if any of the values in the D column are associated with macros I have created for certain values but I am trying to avoid hard coding anything.
I have started doing this by setting up a dictionary in my VBA code but I've never used dictionaries before and the code I have so far isn't working as I'd like. With this code, the cells in the F column of Sheet2 do not turn red.
Option Explicit
Sub estArrays()
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
' Read to dictionary
Dim i As Long
For i = 1 To 17
dict.Add Sheet5.Range("C" & i).Value, 1
Next i
' Read column d
For i = 7 To 446
If dict.Exists(Sheet2.Range("D" & i).Value) Then
' Set to Red
Sheet2.Range("F" & i).Interior.Color = 3
End If
Next i
End Sub
FYI: values are derived from a "MID" formula in column D on Sheet2 so, the values entered in column D are not manually entered. Thanks in advance for any answers/feedback/suggestions.

Related

Conditionally clear contents of range of cells in a row based on cell value

I have an excel file with two sheets: Sheet1 and Sheet2. Sheet 1 has store information while Sheet 2 has product quantity by store information
In Sheet 1, Range "A1:A5" lists 5 store names, Store A through Store E, while range "B1:B5" in Sheet 1 is a drop down box that lets the user choose from the following: "Open", "Closed", or "".
In Sheet 2, there is a table that lists the quantity of products by store. Something like:
I am looking for a way to clear the contents of range B:F in Sheet2 when the respective store in Sheet1 is not set to "Open".
Currently, I am linking the values in Column B from Sheet1 to Column G in Sheet2, and have set the code to the following in Sheet2:
Private Sub Worksheet_Activate()
If Range("G2") <> "Open" Then
Range("B2:F2").ClearContents
End If
How can I perform this in a loop rather than copying this code five separate times?
Something like this?
For i = 2 To 6 'This is the starting row (2) to the ending row (6)
If Range("G" & i) <> "Open" Then 'We use i to dynamically build the range as a string
Range("B" & i & ":F" & i).ClearContents
End If
Next i

Using loop and sum functions with Vlookup

I've got a macro that essentially searches column C in Sheet1 for the value "Rec" and copies the corresponding value in column D, then pastes it into the last open cell in column B of Sheet2. It does just what it is supposed to do and is as follows:
Sub FindPasteGSVInNextCell()
Worksheets("Sheet2").Activate
Range("B" & Rows.Count).End(xlUp).Offset(1, 0).Value = _
WorksheetFunction.VLookup("Rec", Sheet1.Range("C2:H25"), 2, False)
End Sub
I now want the code, instead of just searching for a single "Rec" value, to search for all rows with "Rec" in column C and to sum up all of their corresponding values in column D, then place that sum into Sheet2.
I am assuming that I need some kind of Do Until loop or something, but I am not exactly sure how to format it... I am a beginner with VBA, so any help would be greatly appreciated.
vlookup will not work as it will continue to only grab the first instance of "Rec".
On Sheet 2 list all the possible categories in column A then in column B1 put
= sumif(Sheet1!C:C,A1,Sheet1!D:D)
then copy down. This will Get you the totals by category.
If you want to use VBA, you will still need a list of categories setup somewhere, either hard coded or listed somewhere that you can loop through.
If your list was in column A on Sheet2 then you would:
dim ws as worksheet
set ws = Worksheets("Sheet2")
For each i in ws.range(ws.Range("A1"),ws.Range("A1").offset(xldown)).Cells
i.offset(,1) = WorksheetFunction.Sumif(Worksheets("Sheets1").Range("C:C"), _
i,Worksheets("Sheets1").Range("D:D"))
next i

Excel VBA - Column count using variants

I have searched the forums but I am really struggling to get part of my code to work. Basically the idea is to search sheet 1 and copy one or more columns depending on the criteria to a specific worksheet.
i.e. if sheet 1 columns 1 and 3 contain "copy 01" then copy both columns to a sheet 2 and if sheet 1 columns 2 and 4 contain "copy 02" then copy both columns to a sheet 3 etc.
I can count rows fine using the code, but can't count columns. Seems to relate to not fiding the column range but I have no ideas to fix this! Any help would be much appreciated.
'Row
Dim NR As Long
Dim d As Variant
d = ws1.Range("A1:A" & Cells(Rows.Count, "A").End(xlUp).Row).Value
For NR = 1 To UBound(d, 1)
'column
Dim NC As Long
Dim e As Variant
e = ws1.Range(Cells(1, Columns.Count).End(xlToLeft).Column).Value
For NC = 1 To UBound(e, 1)
Thanks,
Stewart
You want this:
e = range("A1:" & split(cells(1,cells(1,columns.Count).end(xlToLeft).column).address(true,false), "$")(0) & "1").Address
The cells(1, columns.count).end(xlToLeft).column) gets the last column number (for example 13 for 'M').
Putting this into cells(1, lastcolNum) gets a cell that represents the cell in the first row of this column (for example Cell M1).
The address(true, false) method gets the cell reference with a dollar sign before the row but not before the column letter (for example "M$1"
The split function returns an array which splits the input string by the "$" character (for example array - ("M","1")
The (0) returns the 0th element in the returned array (for example "M")
Then putting this into the range function returns the range (for example) "A1:M1"
I'm not entirely sure what you're trying to do with the UBound function here. It would make more sense to make
e = cells(1,columns.count).end(xlToLeft).column
and then loop through
For N = 1 To e
As this will loop through each column.

Excel VBA, compare multiple column values, color cells

I'm new to VBA in Excel and I'm having some trouble. I have 3 columns A, C, and F. I want to highlight only the cells in those columns if they match either of 2 conditions. Highlight any cells with duplicate values in column A, and then only highlight cells in column C and F if column C has a value of 99.99 and greater and Column F has anything but "Test" in the cell.
Sub Highlight()
Dim index As Integer
For index = 1 To 4
'Checks if any cells in Column C has value greater than 99.99 when Column F isn't "Test" or checks if multiple values exist in Column A (which I don't know)
If Range("C1") And Cell.Value > "99.99" And Range("F1") And Cell.Text <> "Current" Then
'Highlighs both cell values Yellow (this is where I run into trouble)
Cell.Interior.ColorIndex = vbYellow
End If
Next index
End Sub
You were just referring to your range wrong. Cell wasn't set. I couldn't see where you were referring to column A though.
Also, if you're using the built in color constants you should use .Color not ColorIndex.
Sub Highlight()
Dim index As Integer
Dim ws As Worksheet
'set the sheet to use
Set ws = Sheet1
For index = 1 To 4
'Checks if any cells in Column C has value greater than 99.99 when Column F isn't "Test" or checks if multiple values exist in Column A (which I don't know)
If ws.Range("C" & index).Value > "99.99" And ws.Range("F" & index).Text <> "Current" Then
'Highlighs both cell values Yellow (this is where I run into trouble)
ws.Range("C" & index).Interior.Color = vbYellow
ws.Range("F" & index).Interior.Color = vbYellow
End If
Next index
End Sub
On a side note. You may be better off looking at using Conditional formatting to achieve what you want rather than VBA.
There is a lot of tutorials about on the internet:
http://chandoo.org/wp/2009/03/13/excel-conditional-formatting-basics/
http://spreadsheets.about.com/od/advancedexcel/tp/090822-excel-conditional-formatting-hub.htm

Excel pulling data from certain cells

I have a file that I only want to extract cells B9, B19, B29, etc etc etc in a pattern throughout the entire file. I would preferably like it to be extracted to a different excel file or someway so that I can do stuff with only those cells in another excel worksheet.
Potentially, I may have several excel files that I may need to do this sort of thing so if there were a way where I had the same format throughout a lot of files that I could always extract cells B9, B19, B29 that would be great. any help appreciated
I looking for syntax if possible
EDIT
Was thinking if I could somehow make an excel IF statement saying if Row has a 9 in it and the row is B then print it somewhere but I want it printed in a column
EDIT 2
I just want column B not A like I mentioned before.
B9, B19,B29,B39 through the whole file
Just in case you want to do it with code:
Sub Test()
'Assumes Sheet1 has your values and Sheet2 will be the data extracted from every row ending in 9
Dim iCounter As Long
Dim newSheetRow As Long
Dim aValue As String
Dim bValue As String
newSheetRow = 1
'Start and nine and increment by 10 till you reach end of sheet
For iCounter = 9 To Sheet1.Rows.Count - 1 Step 10 'NOTE: You may not want to do it by RowCount, but just showing you could
aValue = Sheet1.Range("A" & iCounter)
bValue = Sheet1.Range("B" & iCounter)
Sheet2.Range("A" & newSheetRow).Value = "We were on row: " & iCounter
Sheet2.Range("B" & newSheetRow).Value = aValue
Sheet2.Range("C" & newSheetRow).Value = bValue
newSheetRow = newSheetRow + 1
Next iCounter
MsgBox "Done"
End Sub
You could use the INDIRECT function. It takes a cell reference as a text string and returns the value in that cell. So instead of using
=data!a9
to get the value in sheet "data" in cell a9, you use
=indirect("data!a9")
You can also use r1c1 notation, like this:
=indirect("data!r9c1",false)
From there you can use the ROW and COLUMN functions to go in steps of 10:
=INDIRECT("data!r"&-1+10*ROW()&"c"&COLUMN(),FALSE)
If you put this formula in A1 of your output sheet and then copy and paste it down and across, it will give you the values in data!A9, data!A19, data!A29,... in cells A1, A2, A3... Depending on how you want your output arranged, you might have to modify the cell reference string.
Depending on how often you want to do this depends on how you need to do it, if it's a one of them some simple excel commands might help.
e.g.
In Cell C1 put the following:
=MOD(ROW(),10)
then replicate this down to the bottom of your data. the command will return the numbers 1 through to 0. You can then filter the data on column C where value is 9 then select the visible rows and copy the data to a new sheet.
ROW() ' this returns the ROW number of cell the command is in.
MOD(number, divisor) ' this basically divides one number by the other and returns the remainder. so row 9 / 10 = 0 remainder of 9, row 19 / 10 = 1 remainder of 9.
Hope this helps.