Generate Vote Counting Sheet From Values In Another Sheet - vba

I currently have a worksheet that allows the end user to select from a set of districts and have subdistricts populate along with their vote strength. For instance
District = 5
Candidates = 3
Subdistricts
Subdistrict Vote Strength
U 456
E 442
R 876
T 312
B 256
S 643
I'd like to create a button that let's an end user create an additional sheet that will populate based off of the values in their district selection. The newly created sheet would create a "ballot" of sorts. On the first sheet, they'd indicated the number of candidates and the new sheet would populate similar to this
U E R T B S
Candidate 1
Candidate 2
Candidate 3
The end user would input raw vote (a number between 0 and 4), which would be multiplied by the vote strength in sheet 1, producing a weighted vote calculator that scales up or down depending on the number of subdistricts a certain district has.
The logic would essentially be:
Create a new sheet
Horizontally add column headers for each subdistrict in sheet 1 and add rows for total number of candidates in sheet 1
As raw votes are entered, a mirrored table from the table created in sheet 2 is produced with raw vote calculated

Updated the loop to show the formula instead:
For m = 2 To i + 2
Cells(CandidateCount + 1, m).Formula = _
"=SUM(" & ActiveSheet.Range(ActiveSheet.Cells(2, m), ActiveSheet.Cells(CandidateStart, m)).Address(False, False) & ")"
Next m

So thanks to #VBA Pete for putting me on the right track, I managed to create the basic functionality. I'm now stuck on this step
As raw votes are entered, a mirrored table from the table created in sheet 2 is produced with raw vote calculated
I need to accomplish two things one more step:
1. Create a data validation requirement in a For Loop for a column range that disallows more raw votes being counted than people who are actually present. I have this stored in a variable in the code below as MembersPresent.
2. Populate the weighted vote after end user input is recorded. This can be accomplished by inserting a dynamic formula into cells inside a For loop using variables. I've seperated the working code from the non-working code below
Private Sub CommandButton1_Click()
ActiveWorkbook.Sheets.Add Before:=Worksheets(Worksheets.Count)
i = Sheet1.Cells(8, 6).Value
CandidateCount = Sheet1.Cells(11, 8).Value
CandidateState = CandidateCount + 1
SheetName = Sheet1.Cells(13, 8).Value
OrSheetName = Sheet1.Cells(13, 8).Value
v = 0
For Each Sheet In Worksheets
If SheetName = Sheet.Name Then
SheetName = OrSheetName & "_Ballot" & v
v = v + 1
End If
Next Sheet
ActiveSheet.Name = SheetName
For x = 1 To i
b = 15 + x
Subdistrict = Cells(b, 2).Value
MembersPresent = Cells(b, 6).Value
ActiveSheet.Cells(1, (x + 1)).Value = Subdistrict
For a = 2 To 6
ActiveSheet.Cells(a, x + 1).Value = 0
With ActiveSheet.Range(ActiveSheet.Cells(a, x + 1), ActiveSheet.Cells(a, x + 1)).Validation
.Add Type:=xlValidateWholeNumber, _
AlertStyle:=xlValidAlertStop, _
Operator:=xlBetween, Formula1:="0", Formula2:=MembersPresent
.InputTitle = "Integers"
.ErrorTitle = "Integers"
.InputMessage = "Enter an integer from 0 to " & MembersPresent
.ErrorMessage = "You must enter a number no less than 0 and no greater than the number of members in attendance: " & MembersPresent
End With
Next a
Next x
For b = 1 To CandidateCount
Named = "Candidate Name" & " " & b
ActiveSheet.Cells((b + 1), 1).Value = Named
Next b
ActiveSheet.Cells(CandidateCount + 1, 1).Value = "Raw Vote Totals"
Broken Code that looks like what I think I want
For m = 2 To i + 2
SumRange = ActiveSheet.Range(ActiveSheet.Cells(2, m), ActiveSheet.Cells(CandidateStart, m)).Select
ActiveSheet.Cells(CandidateCount + 1, m).Formula = "=SUM(" & SumRange & ")"
Next m

Related

Concatenate Strings with Do Loop with dynamic column and files

So at Assign sheet I indicate the sheets to take data for each group (each for column and the first row is the explanation of the group). I dynamically can add res at the file or delete
After I use predefined codes to assign which type of discounts / day are applied. At the example I only put two codes (C and S) and one week. For example the raw sheet data for designations Red and Black.
Data product worksheet
Then at Diary I want to show the result of concatenate the B1 value (name of product) each time code fromm price are indicated into the rows. Also I use two loop because at raw product data I have one column for price but at the Diary I have two
Summary page
This is what I finally want to get and doing like that because my boss don't know anything for code and he wan't edite it so I try to do ll dynamic at the sheets :) [I only put two images because i don't have reputations point enough to put more]
With the formula I only get FALSE as answer :(, and I need to get what you can see at summary page
Sub Diary()
Dim I As Integer, x As Integer, y As Integer, z As Integer, n As Integer
Dim p As Integer, d As Integer, f As Integer
Dim a As String, b As String
Dim element As Variant
' Initialize variables I and y at 3 and 4 to begin to show the data at the column I desire. Also x and z were intended to pass the one column mode data sheet to the two column mode at the summary page.
I = 3
x = 1
y = 4
z = 0
With Worksheets("Asign")
.Activate
.Range("B2").Select
End With
' Set the size of Data with sheet names it get form the page assign. It can dynamically changed as size as names of sheets
With ActiveSheet
r = .Cells(.Rows.Count, "B").End(xlUp).Row
End With
Dim Data() As String
ReDim Data(r)
For p = 1 To r - 1
Data(p) = ActiveSheet.Cells(p + 1, "B").Value
Next p
With Worksheets("Diary")
.Activate
.Range("C7").Select
End With
' At Diary concatenate the same cell for all the sheets I have his name stored at Data() and then pass to the next cell with data at raw data sheets (in the images (Red, Black ,... pages). In this case search for code S
Do
Cells(7, I).Select
ActiveCell.Value = ActiveCell.FormulaR1C1 = "=CONCATENATE(" & a & ")"
For Each element In Data
b = ActiveCell.FormulaR1C1 = "IF(Data& !R[-2]C[" & x & "]=""S"",CONCATENATE(Data&!R1C2,"", ""),"""")"
a = b & ";" & b
Next element
x = x - 1
I = I + 2
Loop While I < 4
' The same for the second column of summary sheet called Diary. In this case search for code C
Do
Cells(7, y).Select
ActiveCell.Value = ActiveCell.FormulaR1C1 = _
"=CONCATENATE(" & a & ")"
For Each element In Data
b = ActiveCell.FormulaR1C1 = "IF(Data& !R[-2]C[" & z & "]=""S"",CONCATENATE(Data&!R1C2,"", ""),"""")"
a = b & ";" & b
Next element
z = z - 1
y = y + 2
Loop While I < 4
' Drag and Drop the formula to all the sheet's cells you need
Range("C8:E8").Select
Selection.AutoFill Destination:=Range("C8:E10"), Type:=xlFillDefault
'
End Sub
try this. .... could be simplified by looping through "colors" .... black, red, etc
Sub Diary()
Dim red As Variant
red = Sheets("red").Range("d6:g12") ' put range data into an array for processing
Dim black As Variant
black = Sheets("black").Range("d6:g12")
Dim i As Integer
Dim j As Integer
Dim strC As String
Dim strS As String
For i = 1 To 7
For j = 1 To 4
strC = ""
strS = ""
If LCase(black(i, j)) = "c" Then strC = "Black"
If LCase(black(i, j)) = "s" Then strS = "Black"
If LCase(red(i, j)) = "c" Then
If Len(strC) > 1 Then strC = strC & ";"
strC = strC & "Red"
End If
If LCase(red(i, j)) = "s" Then
If Len(strS) > 1 Then strS = strS & ";"
strS = strS & "Red"
End If
Sheets("diary").Range("c7").Cells(i, j * 2 - 1) = strS
Sheets("diary").Range("c7").Cells(i, j * 2) = strC
Next j
Next i
End Sub

Excel VBA - delete / Copy a record from a sheet to another

Lets Say I have two sheets, Sheet 1 and Sheet 2
I have four columns in sheet1 and three similar column headers in sheet 2.
A record from sheet 1 gets deleted if it is not found in sheet2.
A record from sheet 2 is copied into sheet 1 if it is not already there in sheet 1.
In Sheet1, I have the following columns
Name Age Gender Group
I 25 M A1
A 24 M B1
M 23 M C1
E 23 M D1
In Sheet 2, I have the following columns
Name Age Gender
F 25 M
A 24 M
M 23 M
And my output needs to be in sheet1 :
Name Age Gender Group
A 24 M B1
M 23 M C1
F 25 M
Note : Each Record is Removed / Copied every time as per the combination of Name, Age and Gender and not just the Name alone.
I created a Concatenated column using VBA and now lost for ideas.
For j = 2 To lastrow
strA = Sheets(TabName).Range("A" & j).Value
strB = Sheets(TabName).Range("B" & j).Value
StrC = Sheets(TabName).Range("C" & j).Value
Range(CombinedKeyColLet & j).Value = Application.WorksheetFunction.Concat(strA & strB & StrC)
Cells.Select
Selection.Columns.AutoFit
Next
'Copy or Delete code
'--------------------------------'
Here is the code, that I am trying with On error method
CombinedKeyCol = WorksheetFunction.Match("CombinedKey", Sheets(TabName1).Rows(1), 0)
CombinedKeyColLet = GetColumnLetter(CombinedKeyCol)
For i = lastrow To 2 Step -1
Sheets(TabName2).Activate
CombinedKeyVal = Range(CombinedKeyColLet & i).Value
On Error GoTo Jumpdelete
Present = WorksheetFunction.Match(CombinedKeyVal, Sheets(TabName1).Columns(6), 0)
If Present <> "" Then
GoTo Jumpdontdelete
End If
Jumpdelete:
Sheets(TabName2).Activate
Rows(i & ":" & i).Delete
Present = ""
Jumpdontdelete:
Present = ""
Next
This seems to do the trick. There are two loops here, in the first loop we look at each row in tbl1 and see if it exists in tbl2. If it doesn't, then we delete it. If it does exist, we put its concatenated value in a Dictionary so we can remember it exists in both places. In the second loop, we go over tbl2 and for any concatenated value that doesn't exist in dict (Dictionary) then we know it's a "new" row, so we add this data to tbl1.
Option Explicit
Sub foo()
Dim j As Long
Dim rng As Range
Dim tbl1 As Range, tbl2 As Range
Dim dict As Object
Dim val As String
Dim r As Variant
Dim nextRow
Set dict = CreateObject("Scripting.Dictionary")
With Sheet2
Set tbl2 = .Range("A1:A" & .Range("A" & .Rows.Count).End(xlUp).Row).CurrentRegion
tbl2.Columns(4).Formula = "=c[-3]&c[-2]&c[-1]"
End With
With Sheet1
Set tbl1 = .Range("A1:A" & .Range("A" & .Rows.Count).End(xlUp).Row).CurrentRegion
End With
For j = tbl1.Rows.Count To 2 Step -1
'Does this row exist in Table2?
val = tbl1.Cells(j, 1) & tbl1.Cells(j, 2) & tbl1.Cells(j, 3)
r = Application.Match(val, tbl2.Columns(4), False)
If IsError(r) Then
tbl1.Rows(j).Delete Shift:=xlUp
Else
dict(val) = "" 'Keep track that this row exists in tbl1 AND tbl2
End If
Next
tbl2.Columns(4).ClearContents
Set tbl2 = tbl2.Resize(, 3)
For j = 2 To tbl2.Rows.Count
val = Join(Application.Transpose(Application.Transpose(tbl2.Rows(j).Value)), "")
'If the value doesn't exist, then we add row to Tbl1:
If Not dict.Exists(val) Then
nextRow = tbl1.Cells(1, 1).End(xlDown).Row + 1
tbl1.Rows(nextRow).Resize(, 3).Value = tbl2.Rows(j).Value
End If
Next
End Sub
Note: this necessarily assumes uniqueness in the concatenation of Name/Age/Gender. If there may be duplicates, then this method would need to be modified to not use a Dictionary object, could be done with array or collection etc.

Syntax / Loop Errors

I am coding a nested loop to run through every cell (row and then column) of a table I have. Each cell has a distinct "combination" that it must be equal to, and if it matches values that I am referencing on another sheet, it will take a value (specified in Analysis worksheet) from that same row and return it in this table. Here's my code. I am getting an error in the larger If statement. Any help is appreciated. Thanks!
Updated code, all works except the last "And..." within the if statement. Without it, the code runs, but not correctly (for obvious reasons). When I include it back in, excel freezes up and it never finishes running. Please help.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim i, j, k, m, n As Long
Worksheets("Chart Data").Range("C6:DR10000").Value = ""
j = 3
Do Until Worksheets("Chart Data").Cells(4, j).Value = ""
For i = 4 To Worksheets("Chart Data").Cells(Rows.Count, "A").End(xlUp).Row
k = i + 3
m = i + 2
n = 1
ThisWorkbook.Sheets("Running Avg Log").Activate
' If the current row in running avg log doesnt meet this if statement criteria, it skips & increments i w/o doing anything
If Worksheets("Running Avg Log").Cells(i, 2).Value = 1 _
And Worksheets("Running Avg Log").Cells(i, 3).Value = n _
And Worksheets("Running Avg Log").Cells(i, 4).Value = 1 _
And Worksheets("Running Avg Log").Cells(i, 1).Value = Worksheets("Chart Data").Cells(k, 2).Value Then
' When if statement is entered, this sets the selected dimension # in this accepted row and puts it into corresponding spot in chart data
Worksheets("Chart Data").Cells(m, j).Value = Worksheets("Running Avg Log").Cells(i, 6 + Worksheets("Analysis").Range("C5").Value).Value
n = n + 1
End If
Next i
' j (column number) will increment across after each row in one column is done, testing the entire table
j = j + 1
Loop
End Sub
sheet where code will input the values
sheet where the values are found. If statement looks for date, and the three values following the date. If they match what i want, it returns one of the dimension numbers in that same row. The dimension number is a drop down menu cell selected in the Analysis worksheet, and can be referenced with the cell I have shown in the line within the If statement.
The following updated piece of code works without throwing errors.
However, not sure what do you want to code to do ??
Where exactly are your table's values ? Where do you want to place them ?
Try attaching a screenshot of the desired worksheet results your are trying to obtain.
Sub GraphLoop()
Dim i, j, k, m As Long
Worksheets("Chart Data").Range("C6:DR10000").Value = ""
j = 3
Do Until Worksheets("Chart Data").Cells(4, j).Value = ""
For i = 4 To Worksheets("Chart Data").Cells(Rows.count, "B").End(xlUp).row ' modify according to your Column k = i + 3
m = i + 2
ThisWorkbook.Sheets("Running Avg Log").Activate
' If the current row in running avg log doesnt meet this if statement criteria, it skips & increments i w/o doing anything
If Worksheets("Running Avg Log").Cells(i, 2).Value = 1 _
And Worksheets("Running Avg Log").Cells(i, 3).Value = 1 _
And Worksheets("Running Avg Log").Cells(i, 4).Value = 1 _
And Worksheets("Running Avg Log").Cells(i, 1).Value = Worksheets("Chart Data").Cells(k, 1).Value Then
ThisWorkbook.Worksheets("Chart Data").Activate
' When if statement is entered, this sets the selected dimension # in this accepted row and puts it into corresponding spot in chart data
Worksheets("Chart Data").Cells(m, j).Value = Worksheets("Running Avg Log").Cells(i, 6 + Worksheets("Analysis").Range("C5").Value).Value
End If
Next i
' j (column number) will increment across after each row in one column is done, testing the entire table
j = j + 1
Loop
End Sub

Excel VBA Copy Paste Values with conditions

I'm trying to copy values from one small sheet "MD with ID" to A Larger sheet "D with ID" if 2 fields are identical (consider those two as keys that identify each record).
Here is my first try:
Sub CopyIDCells()
Set i = Sheets("MD with ID")
Set e = Sheets("D with ID")
Dim d
Dim j
d = 1
j = 2
Do Until IsEmpty(e.Range("B" & j))
d = 2
Do Until IsEmpty(i.Range("A" & d))
If e.Range("C" & j).Value = i.Range("D" & d).Value Then
If e.Range("M" & j).Value = i.Range("J" & d).Value Then
e.Range("A" & j).Value = i.Range("B" & d).Value
End If
End If
d = d + 1
Loop
j = j + 1
Loop
End Sub
Here is my second try:
Sub CopyIDCells2()
Set i = Sheets("MD with ID")
Set e = Sheets("D with ID")
Dim d
Dim j
d = 1
j = 2
Do Until j = 20886
d = 2
Do Until d = 1742
If e.Cells(j, 3).Value = i.Cells(d, 4).Value Then
If e.Cells(j, 13).Value = i.Cells(d, 10).Value Then
e.Cells(j, 1).Value = i.Cells(d, 2).Value
End If
End If
d = d + 1
Loop
j = j + 1
Loop
End Sub
Nothing changes in the excel sheet when this code runs, although it takes few minutes to run -_-".
.. sample was removed
So looking at your first CopyIdCells method, there is only one fix I would make to this - make variable d=2. This has headers at the top of your sample data and you need to start on row 2 just like the other sheet.
Sub CopyIDCells()
Set i = Sheets("MD with ID")
Set e = Sheets("D with ID")
Dim d
Dim j
d = 2
j = 2
Do Until IsEmpty(e.Range("B" & j))
d = 2
Do Until IsEmpty(i.Range("A" & d))
If e.Range("C" & j).Value = i.Range("D" & d).Value Then
If e.Range("M" & j).Value = i.Range("J" & d).Value Then
e.Range("A" & j).Value = i.Range("B" & d).Value
End If
End If
d = d + 1
Loop
j = j + 1
Loop
End Sub
Other than that your formulas look good, you just do not have any data that meets your requirements. Add this column to the bottom of "MD with ID" and you will see your code match.
mouse 10 08 11267 A/J M 823 1/11/2008 1 SC-807 LONG 10/10/2005
Since you are matching on "Case Number" AND "Other ID" there are no items in both sheets that meet this criteria. When you add the row above to "MD with ID", you will see the appropriate ID added to your second sheet on several rows.

Copy certain values from one to another column and deleting the original value

I want to copy values from one column to another column (into the same row) if the cell contains the word IN and delete the original value. If not, the code should proceed to the next row and perform a new test. Thus the cell in the target column will remain empty.
When I run the code in Excel nothing happens, so I don't know what is wrong.
Ideally the code should jump to the next column (8) and do the same search and paste the value into the same column (5) when it is done with the first column, but this I haven't started with yet. So I do appreciate tips for that as well :)
Sub Size()
Dim i As Integer, a As String
i = 2
a = "IN"
Do While Cells(i, 7).Value <> ""
If InStr(Cells(i, 7), a) Then
'copying the value to another column but within the same row
Cells(i, 7).Copy Cells(i, 5)
Cells(i, 7).Clear
i = i + 1
Else
i = i + 1
End If
Loop
End Sub
I found out that my first cell in column 7 was empty and thus the Do While Cells(i, 7).Value <> "" wasn't working. Hence I'm refering to a different column that always contain data. Note that the solution code also jumps to the 2 next columns in order to search for the same word.
Sub Size()
Dim i As Integer, a As String
j = 0
i = 1
a = "IN"
Range("A1").Offset(i, 0).Select
For j = 0 To 2
Do Until Selection.Value = ""
If InStr(Range("G1").Offset(i, j).Value, a) Then
Range("E1").Offset(i, 0).Value = Range("G1").Offset(i, j).Value
Range("G1").Offset(i, j).Clear
i = i + 1
Range("A1").Offset(i, 0).Select
Else
i = i + 1
Range("A1").Offset(i, 0).Select
End If
Loop
i = 1
Range("A1").Offset(i, 0).Select
Next j
End Sub