Survey answer to be counted in array - vb.net-2010

I count how many students answering survey Question1 to Question17.
Q1 to Q15 is Likeness questions (strongly disagree / disagree / agree / strongly agree)
Q16 is a Yes / No question: Do you go to the lab?
If students answer Yes (=2) then Q17 is the likeness question. If Q16 is No (=1) then skip Q17
I am able to count from Q1 to Q15 as showed in the codes below, but I am not able to deal with Q16 (y/n). The output requires to show Q1-Q15, skip Q16 and show Q17.
I also have an another table, tblSurveyQuestion(questID, questType, question). At Q16, the questID=Survey16, questType="Y".
Can you please show me how to insert the code to deal with Q16? My code so far:
'assume dt is a datatable that is declared and the connection works
Dim ans(16, 3) As Integer '17 questions with Q16 is a y/n question
For I As Integer = 0 To dt.Rows.Count - 1
If dt.Rows(I).Item(2) = 1 Then
Dim Answer1() As String = dt.Rows(I).Item(3).Split(";")
For j1 As Integer = 0 To 16
Dim k1 As Integer = (Val(Answer1(j1)))
ans(j1, k1 - 1) += 1
Next
End If
Next

Since you are evaluation the answers sequentially and you want to have knowledge of a previous data at some point, you need to know in your code which question are you evaluating (or showing) currently in order to act accordingly.
You already have the evaluated anser of Question 16 in ans(15), so you just need to check if you are at index 16 (=Question17) or not and handle the result of ans(15). One possibility would be to use:
if / elseif / else / end if
or a Select..Case statement
You need to:
declare a variable to store the result of the evaluation of Question16
when evaluation Question17 check the stored result of Question16
act accordingly (for example not saving Question17 or not showing it)
A very simple solution could look like this:
'assume dt is a datatable that is declared and the connection works
Dim ans(16, 3) As Integer '17 questions with Q16 is a y/n question
For I As Integer = 0 To dt.Rows.Count - 1
If dt.Rows(I).Item(2) = 1 Then
Dim Answer1() As String = dt.Rows(I).Item(3).Split(";")
'declare a store for the answer of question 16
Dim answer16IsPositive as Boolean = False
For j1 As Integer = 0 To 16
Dim k1 As Integer = (Val(Answer1(j1)))
ans(j1, k1 - 1) += 1
If (j1 = 15) ' we are at the 16th answer
If (k1 = 1) 'save result of answer 16!
answer16IsPositive = True
End If
End If
If (j1 = 16) ' we are at the 17th answer
If (Not answer16IsPositive)
' deal with answer 17!
'Else
' do nothing
End If
End If
Next
End If
Next

Related

check if string contains specific integer

I have a grid view that has a column containing strings (Middle column).
On the rowDataBound event I want to loop through the column looking for the integer it contains and then display a value in the first column.
I know that the integer range will be 1 to 63 so I can use a FOR loop to loop through the numbers. Here is what I have so far.
For x As Integer = 1 To 63
If CType(e.Row.Cells(2).FindControl("lblTagName"), Label).Text Then
End If
Next
The problem I am having is using contains. I cant use the following as it would also be true for the number 1, 10, 11 etc when x = 1.
For x As Integer = 1 To 63
If CType(e.Row.Cells(2).FindControl("lblTagName"), Label).Text.Contains(x) Then
End If
Next
How do I make sure it only gets one result per number? i.e x = 6 would return UMIS.75OPTR6GROSSMARGIN.F_CV and not all the other strings that contain the number 6.
UPDATE - based on some answers I may not of explained this very well. I want to loop through the gridview and if the number 1 is found and only the number 1 in the second column, not 10 etc then I want to display "Run 1" in the first column. So when x = 10 it will show "Run 10" and so on.
UPDATE 2 - its definatley my explanation, apologies.
The resultant grid view would look like this.
The order of the second column is not set and is not in order.
You'd have to check the entire text of the label to determine whether it is only 1, and not 10, 11, 12, 13, ... as well.
Also, in this case you should use DirectCast rather than CType. CType is only used when converting to different types that include conversion operators, here you are always dealing with a label.
For x As Integer = 1 To 63
If String.Equals(DirectCast(e.Row.Cells(2).FindControl("lblTagName"), Label).Text, "UMIS.75OPTR" & x & "GROSSMARGIN.F_CV", StringComparison.OrdinalIgnoreCase) Then
'Do your stuff.
End If
Next
You might want to think if doing it the other way around. Get the list of numbers in your string with a regular expression match.
Dim s As String = "asd12asdasd.sdf3sdf"
For Each m As System.Text.RegularExpressions.Match In System.Text.RegularExpressions.Regex.Matches(s, "[\d]*")
If m.Success AndAlso Not String.IsNullOrEmpty(m.Value) Then
' m.Value
End If
Next
With that list of number, you can check if it's between 1 and 63.
If your string have the same suffix/prefix, just remove them to show you what the number is.
Dim s As String = "UMIS.75OPTR12GROSSMARGIN.F_CV"
Dim number As String = s.Replace("UMIS.75OPTR", "").Replace("GROSSMARGIN.F_CV", "")
Go backwards in a Do Until Loop:
Dim bolFoundMatch As Boolean = False
Dim intCursor As Integer = 63
Do Until (bolFoundMatch OrElse intCursor = 0)
If CType(e.Row.Cells(2).FindControl("lblTagName"), Label).Text.Contains(intCursor) Then
'Anything you want to do when you find your match.
'This will ensure your loop exits.
bolFoundMatch = True
End If
intCursor -= 1
Loop

Generate n random numbers Summed upto 100 VBA [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Hi I want to generate n random numbers in VBA so that their sum must be 100 and they must be placed in such a way that 7 numbers come on first row then next 7 on second row and so on. I have tried so many solutions given on internet but nothing works for me. So anyone can suggest a solution or give me a link for the solution.
Thanks in advance.
Say we want to make 10 numbers that sum to 100. In A1 enter:
=RANDBETWEEN(1,50)
and in A2 enter:
=IFERROR(RANDBETWEEN(1,100-SUM($A$1:A1)),0)
copy A2 down through A10:
EDIT#1:
To use a macro, try:
Sub randomality()
Dim ary(1 To 10) As Double, zum As Double
Dim i As Long
Randomize
zum = 0
For i = 1 To 10
ary(i) = Rnd
zum = zum + ary(i)
Next i
For i = 1 To 10
ary(i) = ary(i) / zum
Next i
With Application.WorksheetFunction
For i = 1 To 10
Cells(i, "D").Value = Round(100 * ary(i), 0)
Next i
Cells(10, "D").Value = 100 - .Sum(Range("D1:D9"))
End With
End Sub
This puts the values in D1 through D10
The below code will do what you have asked but you have more questions you need to check over: -
Public Sub Sample()
Dim AryNumbers() As Long
Dim LngCounter As Long
ReDim AryNumbers(0)
Randomize
Do Until LngCounter = 100
AryNumbers(UBound(AryNumbers, 1)) = Int(10 * Rnd + 1)
If (LngCounter + AryNumbers(UBound(AryNumbers, 1))) > 100 Then
AryNumbers(UBound(AryNumbers, 1)) = 100 - LngCounter
Else
LngCounter = LngCounter + AryNumbers(UBound(AryNumbers, 1))
ReDim Preserve AryNumbers(UBound(AryNumbers, 1) + 1)
End If
Loop
End Sub
You didn't specify where the numbers are to be stored or if the are to be whole numbers, I have provided them in whole numbers in an array to answer the question.
You need to consider who random the number is, if you looked on the internet you'll know this is a difficult question
I honoured the extra requirement in the comments section of being between 1 and 10.

Is it possible to add cases to a Select Case based on the number of entries in a table?

I've been messing around with VBA in Excel a bit recently; and as a small project for myself, I'm trying to create a "draw names from a hat" sort of macro.
I began by generating a random number, and then choosing which entry from a Table (i.e. ListObject) would be selected using a case statement. The problem with this is that it only works of the number of Table entries is always the same.
So my question (probably a ridiculous one) is: is it possible at all to generate a dynamic 'Select Case' block, where the number of cases on the block is based on the number of entries in the Table?
Thanks.
-Sean
Edit: To clarify: what I am trying to do, exactly, is this:
I generate a random number, i, from 1 to n=10*(number of Table entries). After this, I want to display, in a cell, one of the table entries based on the random number.
Ideally, the code would work similarly to this:
if i = 1 to 10 then choose event 1
if i = 11 to 20 then choose event 2
if i = 21 to 30 then choose event 3
...
if i = (n-9) to n then choose event (n/10)
I hope this helps to clarify the goal of the code.
From our comments here is something you can use:
Sub random()
Dim used_rows As Integer
Dim random As Integer
Dim cell_array() As Integer
used_rows = Sheet1.UsedRange.Rows.Count
ReDim cell_array(used_rows)
For i = 1 To used_rows
cell_array(i - 1) = Cells(i, 1)
Next
random = Int(Rnd * (used_rows))
MsgBox cell_array(random)
End Sub
You can go ahead and change MsgBox to whatever you like, or set like Cell(1,4).Value = cell_array(random), or however you'd like to proceed. It will be based off the number of rows used. Though depending on how you implement your spreadsheet the code might have to be changed a bit.
Here's the update code from the suggestions from the comments. Also remember to use Randomize() in your form initialization or WorkBook Open functions.
Sub random()
Dim used_rows As Integer
Dim random As Integer
'Multiple ways to get the row count, this is just a simple one which will work for most implementations
used_rows = Sheet1.UsedRange.Rows.Count
random = Int(Rnd * (used_rows))
'I use the variable only for the reason that you might want to reference it later
MsgBox Cells(random, 1)
End Sub
This assumes that by "table" you mean "Table with a capital T", known in VBA as a ListObject:
Sub PickRandomTens()
Dim lo As Excel.ListObject
Dim ListRowsCount As Long
Dim RandomNumber As Long
Dim ListEvent As String
Dim Tens As Long
Set lo = ActiveSheet.ListObjects(1)
ListRowsCount = lo.DataBodyRange.Rows.Count
RandomNumber = Application.WorksheetFunction.RandBetween(10, ListRowsCount * 10)
ListEvent = lo.ListColumns("Data Column").DataBodyRange.Cells(Int(RandomNumber / 10))
MsgBox "Random number: " & RandomNumber & vbCrLf & _
"Event: " & ListEvent
End Sub

Creating new columns for values that are repeating more than once so that all the column values will be converted to a row through EXCEL VBA

Im modifying the question that I have already posted. My requirement is very simple.
DEFECT_ID LOG_TIME STATUS
1001 08/22/2012 12:03:34 Open
1001 08/22/2012 12:03:35 Pending
1001 08/23/2012 02:13:46 Fixed
1001 08/23/2012 22:34:37 TestReady
1001 08/24/2012 12:34:43 Pending
1001 08/24/2012 19:13:39 Retest
1001 08/25/2012 22:13:40 Reopen
1001 08/26/2012 10:03:41 Retest
1001 08/27/2012 11:13:42 Closed
The above mentioned format is my 'Source' data. There will be 100s of such defects. As you can see, all the above log date and statuses belong to one single Defect_ID(1001).My actual work is I have to copy the above data into a new sheet in format that helps me to calculate the time difference between the statuses. To your attention, there are 'Eight' defect statuses: Open, Pending,Review,TestReady,Fixed,Retest,Reopen,Closed.And these defect statuses can occur more than one time in a single defect(As shown in above example, 'Pending' occurs twice. But openand closed will occur only once). Similarly there can be upto 6times a status can repeat for a Defect.So I need an output like this, where the log dates will be fitted into the corresponding statuses :
*Defect_ID* Open Pending1 Pending2...Pending6 Fixed1...Fixed6 TestReady1..Testready6 Review1..Review6 Retest1..Retest6 REopen1..REopen6 Closed
Please let me know how to post pictures. if so I can show you how exactly I need the output through VBA. Please refer my other question: 'Copying values from one column that matches a ID to a new sheet by creating new columns for eeach values through EXCEL VBA', all I need in that is, I need new columns added up for every status that is repeating. so that all my values will be into one single row.
Here is some VBA that will do what you are looking for. (If I understand the requirements correctly). It may be a bit verbose, but should be easy to maintain. There is probably a more eloquent way of doing this.
Private Sub CreateOutputSheet()
Dim iLoop, iStartRow, iEndRow As Integer
Dim iPendingCount As Integer
Dim iFixedCount As Integer
'Base Col Numbers
Const colPending As Integer = 3
Const colColFixed As Integer = 9
'.....
Dim sDefectIdCurrent As String
Dim sDefectIdPrevious As String
Dim iTargetRow As Integer
Dim sCurrentStatus As String
Dim dCurrentTime As Date
sDefectIdPrevious = Sheets("Soure").Cells(intstartRow, 1)
sDefectIdCurrent = Sheets("Soure").Cells(intstartRow, 1)
For iLoop = iStartRow To iEndRow
sDefectIdCurrent = Sheets("Soure").Cells(iLoop, 1)
'Check the current problem
If sDefectIdCurrent <> sDefectIdPrevious Then 'Reset the col counters
iPendingCount = 0
iFixedCount = 0
'....
End If
sCurrentStatus = Sheets("Soure").Cells(iLoop, 3)
dCurrentTime = Sheets("Soure").Cells(iLoop, 2)
Select Case sCurrentStatus
Case "Open"
Sheets("Target").Cells(iTargetRow, 2) = dCurrentTime
Case "Pending"
iPendingCount = iPendingCount + 1
Sheets("Target").Cells(colPending + iPendingCount, 1) = dCurrentTime
Case "Fixed"
iFixedCount = iFixedCount + 1
Sheets("Target").Cells(colColFixed + iFixedCount, 1) = dCurrentTime
'...
Case "Closed"
Sheets("Target").Cells(iTargetRow, colClosedNo) = dCurrentTime
End Select
sDefectIdCurrent = Sheets("Soure").Cells(intstartRow, 1)
Next
End Sub

VB - Divide integers doesn't include commas?

This is probably an easy one, but I've got this Excel vba macro where I'm trying to divide two integers and I end up with a round number, even though there should be a comma in there.
For example 278 / 101 = 3. While it's really 2,75 and not 3. Why is this?
The macro is really simple, like this:
Dim intFull, intLow , intDivided as Integer
intFull = 278
intLow = 101
intDivided = intFull \ intLow
Your result variables is an integer
If you work with doubles instead you will get 2.752 etc - which can be rounded using dbDivided = Round(lngFull / lngLow, 2)
[variables updated to be more meaningful]
Sub redone()
Dim lngFull As Long
Dim lngLow As Long
Dim dbDivided As Double
lngFull = 278
lngLow = 101
dbDivided = Round(lngFull / lngLow, 2)
End Sub
Sure you used a forward slash and not a backslash? (See also: http://zo-d.com/blog/archives/programming/vba-integer-division-and-mod.html)