iterate through column and only take item once - excel

picture of sheet where I want to take the values from.
I have a sheet where I want to iterate through one column. Column "E" in sheet3. There are many duplicates in this column. It must take the value, and insert it into sheet1 column "C". It is important that I do not have duplicates in sheet1. I have tried to solve this problem using dictionaries. But I cannot get it to work. Can someone help me?
This is the code i got for now. I am stuck and can not get further.
Sub test()
Const START_ROW = 11
Const MAX_ROW = 40
Const CODE_SHT1 = "C"
Const CODE_SHT4 = "E"
Const CVR_SHT4 = "C"
Const CVR_SHT3 = "C"
Const BROKER_SHT4 = "E"
' sheet 4 columns
'C - Employer CVR MD
'D - Employer name
'E - broker code
'F - Broker name
'? Employer CVR CER
Dim wb As Workbook, wbNew As Workbook
Dim ws1 As Worksheet, ws3 As Worksheet, ws4 As Worksheet, wsNew As Worksheet
Dim iRow As Long, iLastRow, iTargetRow As Long, iCopyRow As Long
Dim msg As String, i As Integer, j As Integer
Dim count As Long, countWB As Integer
Dim WkSht_Src As Worksheet
Dim WkBk_Dest As Workbook
Dim WkSht_Dest As Worksheet
Dim Rng As Range
Set wb = ThisWorkbook
Set ws1 = wb.Sheets("BrokerSelect")
Set ws3 = wb.Sheets("ContributionExceptionReport")
Set ws4 = wb.Sheets("MasterData")
Dim dict As Object, dictCVR As Object, dictBROKER As Object, sKey As String, ar As Variant
Dim sCVR As String, arCVR As Variant
Dim sBROKER As String, arBROKER As Variant
Set dict = CreateObject("Scripting.Dictionary")
Set dictCVR = CreateObject("Scripting.Dictionary")
Set dictBROKER = CreateObject("Scripting.Dictionary")
' Get broker code + broker name from sheet 3 and insert into sheet one
iLastRow = ws4.Cells(Rows.count, BROKER_SHT4).End(xlUp).Row
For iRow = 18 To iLastRow
sKey = ws4.Cells(iRow, BROKER_SHT4)
If dictBROKER.exist(sKey) Then
dictBROKER(sKey) = dictBROKER(sKey) & ";" & iRow ' matched row on sheet 1
Else
dictBROKER(sKey) = iRow
End If
MsgBox (dict(sKey))
Next
End Sub

your code has to be amended from (at least):
a Next statament more (that by the end)
use of dict instead of dictBROKER
incorrect indentation (to have more chance to understand and control it)
so here it is after those changes
Sub Test()
Const START_ROW = 11
Const MAX_ROW = 40
Const BROKER_SHT4 = "E"
Dim wb As Workbook, wbNew As Workbook
Dim ws1 As Worksheet, ws3 As Worksheet, ws4 As Worksheet, wsNew As Worksheet
Dim iRow As Long, iLastRow, iTargetRow As Long, iCopyRow As Long
Dim msg As String, i As Integer, j As Integer
Dim count As Long, countWB As Integer
Dim WkSht_Src As Worksheet
Dim WkBk_Dest As Workbook
Dim WkSht_Dest As Worksheet
Dim Rng As Range
Set wb = ThisWorkbook
Set ws1 = wb.Sheets("BrokerSelect")
Set ws3 = wb.Sheets("ContributionExceptionReport")
Set ws4 = wb.Sheets("MasterData")
Dim dictBROKER As Object, dictCVR As Object, sKey As String, ar As Variant
Dim sCVR As String, arCVR As Variant
Dim sBROKER As String, arBROKER As Variant
Set dictBROKER = CreateObject("Scripting.Dictionary")
' Get broker code + broker name from sheet 3 and insert into sheet one
iLastRow = ws4.Cells(Rows.count, BROKER_SHT4).End(xlUp).Row
For iRow = 13 To iLastRow
sKey = ws4.Cells(iRow, BROKER_SHT4)
If dictBROKER.exists(sKey) Then
dictBROKER(sKey) = dictBROKER(sKey) & ";" & iRow ' matched row on sheet 1
Else
dictBROKER(sKey) = iRow
End If
MsgBox (dictBROKER(sKey))
Next
' add cvr records from sheet3 if any
sBROKER = ws4.Cells(iCopyRow, BROKER_SHT4)
If dictBROKER.exists(sBROKER) Then
arBROKER = Split(dictBROKER(sBROKER), ";")
For j = LBound(arBROKER) To UBound(arBROKER)
If j > 0 Then iTargetRow = iTargetRow + 1
' copy col C to D
iCopyRow = arBROKER(j)
Debug.Print sBROKER, j, iCopyRow
Next
Else
count = count + 1
End If
End Sub

Sub exportSheet2()
Const START_ROW = 11
Const MAX_ROW = 40
Const BROKER_SHT4 = "E"
Dim wb As Workbook, wbNew As Workbook
Dim ws1 As Worksheet, ws3 As Worksheet, ws4 As Worksheet, wsNew As Worksheet
Dim iRow As Long, iLastRow, iTargetRow As Long, iCopyRow As Long
Dim msg As String, i As Integer, j As Integer
Dim count As Long, countWB As Integer
Dim WkSht_Src As Worksheet
Dim WkBk_Dest As Workbook
Dim WkSht_Dest As Worksheet
Dim Rng As Range
Dim r As Long
Set wb = ThisWorkbook
Set ws1 = wb.Sheets("sheet1")
Set ws3 = wb.Sheets("sheet3")
Set ws4 = wb.Sheets("sheet4")
Dim dict As Object, dictCVR As Object, sKey As String, ar As Variant
Dim sCVR As String, arCVR As Variant
Dim sBROKER As String, arBROKER As Variant
Set dict = CreateObject("Scripting.Dictionary")
Set dictCVR = CreateObject("Scripting.Dictionary")
Set dictBROKER = CreateObject("Scripting.Dictionary")
' Get broker code + broker name from sheet 3 and insert into sheet one
iLastRow = ws4.Cells(Rows.count, BROKER_SHT4).End(xlUp).Row
r = 11
For iRow = 13 To iLastRow
sKey = ws4.Cells(iRow, BROKER_SHT4)
If dictBROKER.exists(sKey) Then
dictBROKER(sKey) = dictBROKER(sKey) & ";" & iRow ' matched row on sheet 1
Else
dictBROKER(sKey) = iRow
ws1.Range("E" & r) = sKey
ws1.Range("F" & r) = ws4.Cells(iRow, "F")
r = r + 1
End If
Next

Related

Copying a specific range to all sheets

I wrote this code, but I'm having trouble getting it to work properly.Instead of seeing C2:D5 as a range of ten items, I'd like to see C2 and cell D2 as a single item, and so on. Instead of ten items, the list will essentially consist of five. This is then copied to the appropriate cells D3:E3, as shown below. Is that even possible with vba?
Dim wb As Workbook
Set wb = ThisWorkbook
Dim startsheet As Worksheet
Set startsheet = wb.Sheets("start")
Dim r As Range
Set r = startsheet.Range("C2:D5") '
Dim sh As Worksheet
For Each sh In Worksheets
For i = 1 To r.Count
If Not i + 1 > Worksheets.Count Then Worksheets(i + 1).Range("D3:E3").Value = r.Item(i,1).Value
Next i
Next sh
End Sub ```
The problem in your code was that you were using 2 loops when you only needed one. The loop for the sheets was unnecesary because you were already looping through sheets with the code "Worksheets(i + 1).Range("D3").Value"
Sub test()
Dim wb As Workbook
Set wb = ActiveWorkbook
Dim i As Long
Dim startsheet As Worksheet
Set startsheet = wb.Sheets("start")
Dim r As Range
Set r = startsheet.Range("C2:D5")
Dim sh As Worksheet
For i = 1 To r.Rows.Count
If Not i + 1 > wb.Worksheets.Count Then
Worksheets(i + 1).Range("D3").Value = r.Item(i, 1).Value
Worksheets(i + 1).Range("E3").Value = r.Item(i, 2).Value
Else
End If
Next i
End Sub
Yes, you can easily touch up the code to add sheets if you add more items to column C in startsheet. It'd be like this:
Sub TEST()
Dim wb As Workbook
Set wb = ActiveWorkbook
Dim i As Long, LastRow As Long
Dim startsheet As Worksheet
Set startsheet = wb.Sheets("start")
LastRow = startsheet.Range("C2:C" & Rows.Count).End(xlDown).Row
Dim r As Range
startsheet.Activate
Set r = startsheet.Range(Cells(2, 3), Cells(LastRow, 3))
Dim sh As Worksheet
For i = 1 To r.Rows.Count
If i + 1 > wb.Worksheets.Count Then
Set sh = wb.Sheets.Add(After:=wb.Worksheets(wb.Worksheets.Count))
Worksheets(i + 1).Range("D3").Value = r.Item(i, 1).Value
Worksheets(i + 1).Range("E3").Value = r.Item(i, 2).Value
Else
Worksheets(i + 1).Range("D3").Value = r.Item(i, 1).Value
Worksheets(i + 1).Range("E3").Value = r.Item(i, 2).Value
End If
Next i
End Sub
I will use copy method again, however I will assume the copy sheet is sheet1 and you already created sheet 2 -5 for the function, please try and see and modify for if statement in case you have other issue:
Sub test2()
Dim wb As Workbook
Dim i As Long
Set wb = ThisWorkbook
Dim startsheet As Worksheet
Set startsheet = wb.Sheets("start")
For i = 2 To ThisWorkbook.Worksheets.Count
startsheet.Range("C" & i, "D" & i).Copy Worksheets(i).Range("D3")
Next
End Sub
Copy Each Row to Each Next Worksheet
If you opt for using .worksheets(1) then remove the swsName constant.
Play with the values of the remaining three constants.
Sub CopyRowsForNext()
Const swsName As String = "start"
Const srgAddress As String = "C2:D5"
Const dFirst As String = "D3" ' First Destination Cell
Const wsFirst As Long = 2 ' First Destination Worksheet
Dim wb As Workbook: Set wb = ThisWorkbook
Dim wsCount As Long: wsCount = wb.Worksheets.Count
If wsCount = 0 Then Exit Sub
Dim sws As Worksheet: Set sws = wb.Worksheets(swsName)
' Maybe this would be more appropriate (forgetting about "start"):
'Dim sws As Worksheet: Set sws = wb.Worksheets(1)
Dim srg As Range: Set srg = sws.Range(srgAddress)
Dim srCount As Long: srCount = srg.Rows.Count
Dim scCount As Long: scCount = srg.Columns.Count
Dim cIndex As Long
Dim r As Long
For r = 1 To srCount
cIndex = r + wsFirst - 1
If cIndex <= wsCount Then
wb.Worksheets(cIndex) _
.Range(dFirst).Resize(, scCount).Value = srg.Rows(r).Value
End If
Next r
End Sub
Sub CopyRowsForEachNext()
Const swsName As String = "start"
Const srgAddress As String = "C2:D5"
Const dFirst As String = "D3" ' First Destination Cell
Const wsFirst As Long = 2 ' First Destination Worksheet
Dim wb As Workbook: Set wb = ThisWorkbook
Dim wsCount As Long: wsCount = wb.Worksheets.Count
If wsCount = 0 Then Exit Sub
Dim sws As Worksheet: Set sws = wb.Worksheets(swsName)
' Maybe this would be more appropriate (forgetting about "start"):
'Dim sws As Worksheet: Set sws = wb.Worksheets(1)
Dim srg As Range: Set srg = sws.Range(srgAddress)
Dim srCount As Long: srCount = srg.Rows.Count
Dim scCount As Long: scCount = srg.Columns.Count
Dim srrg As Range
Dim cIndex As Long
Dim n As Long
For Each srrg In srg.Rows
n = n + 1
cIndex = n + wsFirst - 1
If cIndex <= wsCount Then
wb.Worksheets(cIndex) _
.Range(dFirst).Resize(, scCount).Value = srrg.Value
End If
Next srrg
End Sub

append value to list within loop

I am running through a column and storing the value for each row in a dictionary.
if the value does not exists i want to add a cell value on that row to an array/list. In the end i want a sum of all the values in the array.
How do i append the values to an array and sum the values in the array? I hope someone can help
Code
Const NETSCONT_SHT3 = "D"
Const NETSCONT_SHT4 = "I"
Const NETSEXP_SHT4 = "H"
Const MEMBER_SHT4 = "G"
Dim wb As Workbook, wbNew As Workbook
Dim ws1 As Worksheet, ws3 As Worksheet, ws4 As Worksheet
Dim iRow As Long, iLastRow, iTargetRow As Long, iCopyRow As Long, NbCont_SHT3 As Long, AmCont_SHT3 As Double
Dim NbCont_SHT4 As Long, AmCont_SHT4 As Double, NbResults As Integer, AmResult As Double, pct_change As Double
Dim msg As String, i As Integer, j As Integer
Dim count As Long, countWB As Integer
Dim WkSht_Src As Worksheet
Dim WkBk_Dest As Workbook
Dim WkSht_Dest As Worksheet
Dim Rng As Range
Dim r As Long
Dim d As Long, dE As Long
Set wb = ThisWorkbook
Set ws1 = wb.Sheets("BrokerSelect")
Set ws3 = wb.Sheets("ContributionSplitReport")
Set ws4 = wb.Sheets("ContributionExceptionReport")
Dim dict As Object, dictEXP As Object, dictRESULTP As Object, dictRESULTN As Object, dictMEMBER As Object, sKey As Double, ar As Variant
Dim sEXP As Double, sRESP As Double, sRESN As Double, sMEMBER As Integer, arEXP As Variant, arRESP As Variant, arRESN As Variant, arMEMBER As Variant
Set dict = CreateObject("Scripting.Dictionary")
Set dictEXP = CreateObject("Scripting.Dictionary")
Set dictRESULTP = CreateObject("Scripting.Dictionary")
Set dictRESULTN = CreateObject("Scripting.Dictionary")
Set dictMEMBER = CreateObject("Scripting.Dictionary")
iLastRow = ws4.Cells(Rows.count, MEMBER_SHT4).End(xlUp).Row
For iRow = 18 To iLastRow
sMEMBER = ws4.Cells(iRow, MEMBER_SHT4) ' column "G"
sKey = ws4.Cells(iRow, NETSCONT_SHT4) ' column "I"
sEXP = ws4.Cells(iRow, NETSEXP_SHT4) ' column "H"
If dictMEMBER.exists(sMEMBER) Then
dictMEMBER(sMEMBER) = dictMEMBER(sMEMBER) & ";" & iRow
Else
dictMEMBER(sMEMBER) = iRow
If sKey <> "0" Then
pct_change = (sKey - sEXP) / sKey
If pct_change > 0 Then
dictRESULTP.Add d, pct_change: d = d + 1
ElseIf pct_change < 0 Then
dictRESULTN.Add dE, pct_change: dE = dE + 1
End If
End If
'If dictMEMBER(sMEMBER) does not exist I want to append the cell value (irow, i) into an array.
'In the end i want to sum the value of the array
End If
next
I'm not entirely clear about what you wish to achieve but the code below will do most of it. Please try it.
Sub Benchmark()
' This proc needs a reference to 'Miscrosoft Scripting Runtime'
' If you use late binding VBA will do without the reference but you
' won't have the benefit of Intellisense drop-downs while programming.
' Checkmark: Tools > References > Microsoft Scripting Runtime'
Const ConExMember = "G"
Const ConExExp = "H"
Const ConExAct = "I"
Dim Wb As Workbook
Dim WsConEx As Worksheet
Dim Dict As Scripting.Dictionary
Dim Member As String
Dim Expected As Double, Actual As Double
Dim ChangePct As Double
Dim Rl As Long ' last row
Dim R As Long ' rows loop counter
Dim Tmp As Variant
Dim Msg As String, Count(2) As Integer
Set Wb = ThisWorkbook
Set WsConEx = Wb.Sheets("ContributionExceptionReport")
Set Dict = CreateObject("Scripting.Dictionary")
' pct change in expected and actual cont
With WsConEx
Rl = .Cells(.Rows.Count, ConExMember).End(xlUp).Row
For R = 18 To Rl
Member = .Cells(R, ConExMember).Value
Actual = Val(.Cells(R, ConExAct).Value)
Expected = Val(.Cells(R, ConExExp).Value)
On Error Resume Next ' if Actual = 0
ChangePct = (Actual - Expected) / Actual
If Err.Number Then ChangePct = 0
On Error GoTo 0
If Not Dict.Exists(Member) Then
Dict.Add Member, ChangePct
End If
Next R
End With
ChangePct = 0
For Each Tmp In Dict.Keys
ChangePct = ChangePct + Dict(Tmp)
R = Sgn(Dict(Tmp)) + 1
Count(R) = Count(R) + 1
Next Tmp
Msg = "Members: " & Dict.Count & vbCr & _
"Increases: " & Count(2) & vbCr & _
"Decreases: " & Count(1) & vbCr & _
"Unchanged: " & Count(0) & vbCr & _
"Change % : " & Round(ChangePct * 100, 2) & "%"
MsgBox Msg, vbInformation, "Summary"
End Sub
The code will loop through all your members in what was your Ws4. It will skip over duplicates. Unique members will be added to a dictionary with their names (or perhaps ID numbers) as Key and the percentage of change as Item. The result will be one dictionary with all unique names and all the changes.
In the second half of the code this dictionary is examined. Changes are sorted into positive, negative and unchanged and counted for each category. The aggregate change is calculated and the members counted. All of that goes into a message box.
The important change I made is to create pairs of data, with the member ID as key and the change as related information. This data can be evaluated easily, with very few lines of code, whichever way you want.
I update the code as following hoping it would be helpful to you:
Sub AddAndSumMissingDictionary()
'Constants
Const NETSCONT_SHT3 = "D"
Const NETSEXP_SHT4 = "H"
Const NETSCONT_SHT4 = "I"
Const MEMBER_SHT4 = "G"
'ArrayColumns
Const cTotalExpected = 0
Const cTotalNets = 1
Const cTotalNetSplitAVC = 2
'Workbooks & Worksheets
Dim wb As Workbook, wbNew As Workbook
Dim ws1 As Worksheet, ws3 As Worksheet, ws4 As Worksheet
Dim WkSht_Src As Worksheet
Dim WkBk_Dest As Workbook
Dim WkSht_Dest As Worksheet
'Array you Requested
Dim ArrMissingDictionary() As Double
Dim lMissingDictCount As Long
'Iteration Rows & Ranges
Dim iRow As Long, iLastRow As Long, iTargetRow As Long, iCopyRow As Long, NbCont_SHT3 As Long, AmCont_SHT3 As Double
Dim NbCont_SHT4 As Long, AmCont_SHT4 As Double, NbResults As Integer, AmResult As Double, pct_change As Double
Dim msg As String, i As Integer, j As Integer
Dim count As Long, countWB As Integer
Dim Rng As Range
Dim r As Long
Dim d As Long, dE As Long
'Initializing Variables
Set wb = ThisWorkbook
Set ws1 = wb.Sheets("BrokerSelect")
Set ws3 = wb.Sheets("ContributionSplitReport")
Set ws4 = wb.Sheets("ContributionExceptionReport")
Dim dict As Object, dictEXP As Object, dictRESULTP As Object, dictRESULTN As Object, dictMEMBER As Object, sKey As Double, ar As Variant
Dim sEXP As Double, sRESP As Double, sRESN As Double, sMEMBER As Integer, arEXP As Variant, arRESP As Variant, arRESN As Variant, arMEMBER As Variant
'Initializing Dictionaries
Set dict = CreateObject("Scripting.Dictionary")
Set dictEXP = CreateObject("Scripting.Dictionary")
Set dictRESULTP = CreateObject("Scripting.Dictionary")
Set dictRESULTN = CreateObject("Scripting.Dictionary")
Set dictMEMBER = CreateObject("Scripting.Dictionary")
'Set Missing lMissingDictCount to 0
lMissingDictCount = 0
'Get the Last Row
iLastRow = ws4.Cells(Rows.count, MEMBER_SHT4).End(xlUp).Row
'Iteration Process
For iRow = 18 To iLastRow
sMEMBER = ws4.Cells(iRow, MEMBER_SHT4) ' column "G"
sKey = ws4.Cells(iRow, NETSCONT_SHT4) ' column "I"
sEXP = ws4.Cells(iRow, NETSEXP_SHT4) ' column "H"
'Checking Existance of Dictionary Entry
If dictMEMBER.exists(sMEMBER) Then
'I think this should be like this
dictMEMBER.Key(sMEMBER) = dictMEMBER(sMEMBER) & ";" & iRow 'dictMEMBER(sMEMBER) = dictMEMBER(sMEMBER) & ";" & iRow
Else
dictMEMBER.Key(sMEMBER) = iRow 'dictMEMBER(sMEMBER) = iRow
If sKey <> "0" Then
pct_change = (sKey - sEXP) / sKey
If pct_change > 0 Then
dictRESULTP.Add d, pct_change: d = d + 1
ElseIf pct_change < 0 Then
dictRESULTN.Add dE, pct_change: dE = dE + 1
End If
End If
'Increment lMissingDictCount
lMissingDictCount = lMissingDictCount + 1 'UBound(ArrMissingDictionary, 1) + 1
'Adding the Array:
ReDim Preserve ArrMissingDictionary(2, lMissingDictCount) 'Increasing the Array Row while keeping its content
ArrMissingDictionary(cTotalExpected, lMissingDictCount) = ws4.Cells(iRow, NETSEXP_SHT4)
ArrMissingDictionary(cTotalNets, lMissingDictCount) = ws4.Cells(iRow, NETSCONT_SHT4)
ArrMissingDictionary(cTotalNetSplitAVC, lMissingDictCount) = ws4.Cells(iRow, MEMBER_SHT4)
'If dictMEMBER(sMEMBER) does not exist I want to append the cell value (irow, i) into an array.
End If
Next iRow
'In the end i want to sum the value of the array
'I'm reusing the iRow again
Dim dTotalExpected As Double, dTotalNets As Double, dTotalNetSplitAVC As Double
For iRow = LBound(ArrMissingDictionary, 1) To UBound(ArrMissingDictionary, 1)
dTotalExpected = dTotalExpected + ArrMissingDictionary(cTotalExpected, iRow) 'Sum Missing on Col "H"
dTotalNets = dTotalNets + ArrMissingDictionary(cTotalNets, iRow) 'Sum Missing on Col "I"
dTotalNetSplitAVC = dTotalNetSplitAVC + ArrMissingDictionary(cTotalNetSplitAVC, iRow) 'Sum Missing on Col "G"
Next iRow
'You can affect the dTotalExpected, dTotalNets and dTotalNetSplitAVC for your purpose
End Sub
Hopefully, this will solve your issue

calculating with dictionary keys

I am trying to calculate the percentage difference in two columns. I have stored the values in two different dictionaries and calculating the percentage difference. The result is stored in a value = pct_change.
I then want to add it to a list, so i counts how many of the values that had a percentage increase and how many had a percentage decrease. Is it possible to create a new dictionary, store the pct_change as a key, and append the key in the new dictionary? After the loop then counting the number of keys in the dictionary?
I will post my current code below. Note that I am aware of the many defined variables that i am not using.
I hope someone can help me out
Sub benchmark()
Const NETSCONT_SHT3 = "D"
Const NETSCONT_SHT4 = "I"
Const NETSEXP_SHT4 = "H"
Dim wb As Workbook, wbNew As Workbook
Dim ws1 As Worksheet, ws3 As Worksheet, ws4 As Worksheet
Dim iRow As Long, iLastRow, iTargetRow As Long, iCopyRow As Long, NbCont_SHT3 As Long, AmCont_SHT3 As Double
Dim NbCont_SHT4 As Long, AmCont_SHT4 As Double, NbResults As Integer, AmResult As Double, pct_change As Double
Dim msg As String, i As Integer, j As Integer
Dim count As Long, countWB As Integer
Dim WkSht_Src As Worksheet
Dim WkBk_Dest As Workbook
Dim WkSht_Dest As Worksheet
Dim Rng As Range
Dim r As Long
Set wb = ThisWorkbook
Set ws1 = wb.Sheets("BrokerSelect")
Set ws3 = wb.Sheets("ContributionSplitReport")
Set ws4 = wb.Sheets("ContributionExceptionReport")
Dim dict As Object, dictEXP As Object, sKey As Double, ar As Variant
Dim sEXP As Double, arEXP As Variant
Set dict = CreateObject("Scripting.Dictionary")
Set dictEXP = CreateObject("Scripting.Dictionary")
' pct change in expected and actual cont
iLastRow = ws4.Cells(Rows.count, NETSCONT_SHT4).End(xlUp).Row
For iRow = 18 To iLastRow
sKey = ws4.Cells(iRow, NETSCONT_SHT4)
sEXP = ws4.Cells(iRow, NETSEXP_SHT4)
If sKey <> "0" Then
pct_change = (sKey - sEXP) / sKey
MsgBox (pct_Change)
Else
End If
Next
End Sub
For your last request, please replace
MsgBox (pct_Change)
with
Dim d As Long, dE as Long
If pct_Change > 0 Then
dict.Add d, pct_Change: d = d + 1
ElseIf pct_Change < 0 Then
dictEXP.Add dE, pct_Change: dE = dE + 1
End If
'finally:
Debug.Print dict.Count, dictEXP.Count, dictEXP.Items(2)

Loop through table and extract certain values

I have a table with project details and their expiration dates. If the project is expired, it outputs it to another sheet.
I'm trying to make a Refresh button on the Expired project sheet that would loop through that table and extract all of the expired projects.
Sub refresh_expired()
Dim wsMaster As Worksheet: Set wsMaster = Worksheets("MASTER")
Dim wsList As Worksheet: Set wsList = Worksheets("LIST")
Dim tblList As ListObject: Set tblList = wsList.ListObjects("digsafe_list")
Dim tblExp As ListObject: Set tblExp = wsMaster.ListObjects("expired_list")
Dim tblList_row As ListRow
Dim tblExp_row As ListRow
Dim not_empty As String
Dim temp_digsafe As String, temp_work As String
Dim temp_date As Date
Dim tRows As Long, tCols As Long
If tblList.DataBodyRange.Rows.count <> 0 Then
Set tblExp_row = tblExp.ListRows.Add
Set tblList_row = tblList.ListRows.Add
For i = 1 To tblList.DataBodyRange.Rows.count
If tblList_row.Range(7, i).Value < 1 Then
temp_digsafe = tblList_row.Range(1, 1).Value
tblExp_row.Range(1, i).Value = temp_digsafe
temp_date = tblList_row.Range(7, i).Value
tblExp_row.Range(1, 4).Value = temp_date
i = i + 1
End If
Next
End If
End Sub

Selecting a random word from a list

I am trying to get my macro(next word) to select a random word from a list and then another macro(definition) does a vlookup to return the definition. When I select the macro to grab a new word I need it to clear the macro for the definition so that I cant see it until i select the definition button. Right now i get runtime error 1004 and it highlights my .clearcontent code at the end.
Sub showRandomWord()
Dim ws As Worksheet, ws2 As Worksheet
Dim stRow As Long, endRow As Long, dataCol As Long
Dim dispRow As Long, dispCol As Long
Set ws = Sheets("Sheet1")
Set ws2 = Sheets("Sheet2")
stRow = 2
dataCol = 1
dispRow = 2
dispCol = 2
With ws
endRow = .Cells(.Rows.Count, dataCol).End(xlUp).Row
End With
ws2.Cells(dispRow, dispCol).Value =
ws.Cells(Application.RandBetween(stRow, endRow), dataCol).Value
Worksheets("Sheet2").Range("J2").ClearContents
End Sub
Use MergeArea?
Sub showRandomWord()
Dim ws As Worksheet, ws2 As Worksheet
Dim stRow As Long, endRow As Long, dataCol As Long
Dim dispRow As Long, dispCol As Long
Set ws = Sheets("Sheet1")
Set ws2 = Sheets("Sheet2")
stRow = 2
dataCol = 1
dispRow = 2
dispCol = 2
With ws
endRow = .Cells(.Rows.Count, dataCol).End(xlUp).Row
End With
ws2.Cells(dispRow, dispCol).Value = ""
ws.Cells(Application.RandBetween(stRow, endRow), dataCol).Value
ws2.Range("J2").MergeArea.ClearContents
End Sub

Resources