Picking up information from looped userform - vba

I'm using VBA in Excel and I'm stuck somewhere.
In my code I'm showing n times an userform with textboxes from which I would like to pick up the information each time the Userform is shown, in different cells not to lose the information.
I'm kind of helpless, any help would be welcomed.
This is the userform From which I would like to use the data:
In order to show x times the userform and change its caption each times I use the following code:
For i = 1 To ntrav - 1
AppInt.Caption = "Appuis intermédiaires n°" & i
AppInt.Show
Then in my loop where, before, I selected a cell from the sheet I'm interested in using the data from the textboxes:
If AppInt.CheckBox1Int = True Then
ActiveCell.Offset(i, 3).Value = "FX FY ZZ " & AppInt.TextBox1Int.Value
ActiveCell.Offset(i + 1, 3).Value = "FX FY FZ "
ActiveCell.Offset(i + 2, 3).Value = "FX FY ZZ " & AppInt.TextBox1Int.Value
ElseIf AppInt.CheckBox2Int = True Then
ActiveCell.Offset(i, 3).Value = "XX " & AppInt.TextBox3Int.Value & " FY ZZ " & AppInt.TextBox2Int.Value
ActiveCell.Offset(i + 1, 3).Value = "FX FY FZ "
ActiveCell.Offset(i + 2, 3).Value = "XX " & AppInt.TextBox3Int.Value & " FY ZZ " & AppInt.TextBox2Int.Value
End If
ActiveCell.Offset(2, 0).Select
Call Unload(AppInt)
Next i

You have 2 problems. Firstly you use ActiveCell.Offset(i), meaning write the data (i) rows relative to the current selected cell. However you also
ActiveCell.Offset(2, 0).Select
Which moves the selection on each step of the loop. This means each step of the loop you offset twice, once by moving the ActiveCell, once using i to look relative to this cell (and i keeps increasing)
So my advice is to save the ActiveCell to a variable at the top of your code then offset relative to that:
Dim firstRow As Range
Set firstRow = ActiveCell
'...
'everything is offset relative to firstRow
firstRow.Offset(i + 1, 3).Value = "FX FY FZ "
And remove the Select statements entirely.
The second problem is a bit more subtle and I'll wait till you have formatted your code correctly for that.

Related

Edit value of cells in a specific column if a condition is not met using Excel VBA

I need a macro that will apply the below-mentioned formula in column J if the value of a cell in column C is "Hits_US" and the value of a cell in column D is "harry". Below is the formula
=((Column G*32)+(Column H*28)+300)/60
Please note that there will be other values in column J. So, only if the condition is met, the formula has to be applied.
I tried to do this in parts. I first tried to multiply the value in column G by 32. But it did not work.
For i = 1 To 10
If Sheets(1).Range("C" & i).Value = "Hits_US" And Range("D" & i).Value <> "harry" Then
Cells(i, 10) = Cells(i, 7) * 32
End If
Next i
You should be able to avoid a loop
Sheets(1).Range("J1:J10").Formula = "=IF(AND(C1=""Hits_US"",D1=""Harry""),(G1*32+H1*28+300)/60,"""")"
For all rows in J, based on how many entries are in column C
With Sheets(1)
.Range("J1:J" & .Range("C" & Rows.Count).End(xlUp).Row).Formula = "=IF(AND(C1=""Hits_US"",D1<>""Harry""),(G1*32+H1*28+300)/60,"""")"
End With
If you want to leave a formula in cells then I'd go with R1C1 notation:
Sheets(1).Range("J1:J10").FormulaR1C1 = "=IF(AND(RC3=""Hits_US"",RC4=""harry""),(RC7*32+RC8*28+300)/60,"""")"
While if you want to leave only the formula results then you have to possibilities:
have formulas do the math and then leave only values
With Sheets(1).Range("J1:J10")
.FormulaR1C1 = "=IF(AND(RC3=""Hits_US"",RC4=""harry""),(RC7*32+RC8*28+300)/60,"""")"
.Value = .Value
End With
have VBA do the math and write its results directly
With Sheets(1)
For i = 1 To 10
If .Range("C" & i).Value = "Hits_US" And .Range("D" & i).Value = "harry" Then
.Cells(i, 10) = (.Cells(i, 7) * 32 + .Cells(i, 8) * 28 + 300) / 60
End If
Next
End With

Excel data from colum to row

I have data like in the picture below:
I need to (with a macro) arrange the data so that every row with a number after ELEVATION\AZIMUTH be in the first row, like in picture:
I have a lot of rows like this data. Maybe any one can help?
This is not tested. you can give it a try. the below can be written in diff way as well.
Sub test1()
Dim LastRow, DataCount, temp As Double
i = 1
LastRow = 1
Do While LastRow <> 0
Range("A" & i).Select
If ActiveCell.Value = "ELEVATION\AZIMUTH" Then
'Cut all three row and paste
DataCount = Application.WorksheetFunction.CountA(Range(i & ":" & i))
Range("A" & ActiveCell.Row + 1, "I" & ActiveCell.Row + 1).Cut ActiveCell.Offset(0, DataCount)
Range("A" & ActiveCell.Row + 2, "I" & ActiveCell.Row + 2).Cut ActiveCell.Offset(0, DataCount * 2)
Range("A" & ActiveCell.Row + 3, "I" & ActiveCell.Row + 3).Cut ActiveCell.Offset(0, DataCount * 3)
Else
LastRow = Application.WorksheetFunction.CountA(Range("A" & i, "A" & i + 10))
End If
i = i + 1
Loop
End Sub
This can also be done without the use of macros.
I am assuming your last column where data is there is column I and the row number is 11. You want to fill all cells in row 11 after column I, i.e. J11,K11.... with values right below I11
You could do this, paste in J11
J11=INDEX($I$11:$I$1000,COLUMN(B1),1)
Drag the formula across the row and you should get your desired output

Execution of internal loop - Error 'Type Mismatch'

I'm writing a macro for the first time and I have a problem with one of my Subs.
When it runs the first time when ROW = 3 it does the internal loop for the Col = 3 to Col = x-2 without any problem. However when ROW increase to 4 I get an Error on the first run of the internal Col loop (Col = 3).
The Error says Run-time error '13' and Type mismatch, however I don't understand why it would run thru ok on first execution of the loop when ROW = 3 but fail when ROW = 4.
For Row = 3 To y - 1
Col = 0
OutputCol = OutputCol + 1
For Col = 3 To x - 2
Cells(Col + 3, OutputCol).Value = "L" + Cells(5, Col + 1).Value + "C" + Cells(6, Row).Value + " " + "EXEC TRANEXEC, " + Line + Cells(5, Col + 1).Value + "," + Company + Cells(6, Row).Value
Next Col
Next Row
Any help greatly appreciated.
Thanks
Marty
Value is not necessarily a string. And #Comintern is right - don't redefine Row. Assuming you change Row to RowNum, try this in your loop:
Cells(Col + 3, OutputCol).Value = "L" & CStr(Cells(5, Col + 1).Value) & _
"C" & CStr(Cells(6, RowNum).Value) & " " & _
"EXEC TRANEXEC, " & Line & CStr(Cells(5, Col + 1).Value) & "," & _
Company & CStr(Cells(6, RowNum).Value)
The CStr() calls make sure that you get a string representation of Value, so that the string-concatenation operator & will always have strings to work with.
Edit
As #Mat's Mug noted, before the code snippet you included, you should be doing something like:
Dim ws as Worksheet
set ws = ActiveSheet
(or whatever worksheet you want instead of ActiveSheet). Then every call to Cells should be to ws.Cells instead. That way you will always know which worksheet you are referring to, and you won't have weird errors that depend on factors beyond your control.
Similarly, instead of ActiveWorkbook, do Dim wb as Workbook and use, e.g., wb.Sheets.

Generate Vote Counting Sheet From Values In Another Sheet

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

Outputting recurring events within a loop VBA

I am currently analyzing a schedule with color coded events that occur in a row and the time expands over the columns (there is only color in the cells no text, yes it's dumb but it's out of my control). I am currently able to print the result for one occurrence of an event into another worksheet, but I cannot determine how to make it print the dates for recurring events in different cells (it currently only prints the last time an event occurs). My current code is:
For i = 2 To 93
If Cells(7, i).Interior.Color = "8421631" And Cells(7, i - 1).Interior.Color = "16777215" Then
startDay = Cells(3, i).Value
startMonth = Cells(1, i).Value
name = Cells(7, i).Value
Worksheets("Sheet1").Activate
ActiveWorkbook.Worksheets("Sheet1").Cells(2, 1) = startDay + startMonth
End If
If Cells(7, i).Interior.Color = "8421631" And Cells(7, i + 1).Interior.Color = "16777215" Then
endDay = Cells(3, i).Value
endMonth = Cells(1, i).Value
ActiveWorkbook.Worksheets("Sheet1").Cells(2, 2) = endDay + endMonth
End If
Next i
All of my variables are entered as strings. I attempted a few different methods with no success. I feel that I need to add another loop in my IF statement, but I am unsure as to how to best do it. Overall the code achieves its purpose (previously used message boxes for output to confirm it was operating as it should). This is just a small part of the overall code, but with this answer I would be able to apply it elsewhere.
for what I could grasp out of your description you may try this code:
Option Explicit
Sub main()
Dim i As Long
For i = 2 To 93
If Cells(7, i).Interior.Color = "8421631" Then
If Cells(7, i - 1).Interior.Color = "16777215" Or Cells(7, i + 1).Interior.Color = "16777215" Then
WriteDate Cells(3, i).Value, Cells(1, i).Value
End If
End If
Next i
End Sub
Sub WriteDate(day As String, month As String)
With ActiveWorkbook.Worksheets("Sheet1")
.Cells(2, .Columns.Count).End(xlToLeft).Offset(, 1) = day & "/" & month
End With
End Sub