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
Related
I have numbers from 1 to 25, four numbers will show up daily. I need to put a +1 on each of the four numbers and need to put a -1 on each of the 21 numbers didn't show up.
The four numbers that come up daily will be inputted in four different text boxes. The count being positive or negative needs to go on 25 separate text boxes labeled 1 thru 25.
I have tried "if textbox <> number, then count -= 1" but I get a count of -4 because it doesn't see the number in any of the four text boxes.
I only need a daily count not a textbox count. Sorry I don't have any code started and would greatly appreciate if someone can point me in the right direction. I'm doing this on Visual Studio 2012.
Thank you all for responding. Here is some code I've started but the count is not correct. My four input text boxes are in GroupBox2. Four numbers from 1 to 25 will draw daily like a lottery. The four numbers drawn will have a value of +1 each all others -1. I need to find the age of each number 1 thru 25. If a number has a +3 then that means that number has drawn 3 consecutive days. If a number has a -15 then that means that number has not drawn for the past 15 days.
Dim tb As New TextBox
Dim ctrl As Control
Dim Counter As Integer
For Each ctrl In GroupBox2.Controls
tb = ctrl
If tb.Text = 1 Then
Counter += 1
ElseIf tb.Text <> 1 Then
Counter -= 1
TextBox464.Text = Counter
End If
If tb.Text = 2 Then
Counter += 1
ElseIf tb.Text <> 2 Then
Counter -= 1
TextBox463.Text = Counter
End If
If tb.Text = 3 Then
Counter += 1
ElseIf tb.Text <> 3 Then
Counter -= 1
TextBox462.Text = Counter
End If
If tb.Text = 4 Then
Counter += 1
ElseIf tb.Text <> 4 Then
Counter -= 1
TextBox461.Text = Counter
End If
Next
We will need more information about how your going to approach it to be able to help you further, but as for your problem with this If Textbox <> number Then count -= 1 you can use something like this since your only going to be having numbers on the textboxes If Cint(Textbox.Text) <> number then count -= 1 since your using just Textbox its attempting to evaluate it as a control and not the property that your looking for, you need to read from its .Text Property, However since its evaluated as a String and not an Integer it will throw an error exception, thats why the Cint() is included (This may also be used to convert it to integer Ctype(number, Integer) Not sure if there is an execution speed difference or not, however Cint() is a faster way of writing it.) it will try and convert the String into an Integer and when its converted into an integer it can be evaluated like one using <>. No one is going to write a whole solution out for you, but while you attempt to create it yourself and more information can be added we are more than happy to help you with problems along the way.
I am trying to loop through a range in column A and delete each row where the value in cell A starts with a letter (e.g. delete C159, but not 8T9G3). I think the code may work correctly, if I get the between piece straight. Any suggestions how I can get the code to work?
Sub DeleteLetterRows()
Dim k as integer
For k = 2 To 100
If Asc(ActiveSheet.Range("A" & k).value) >=65 and <=90 or >=97 and <=122
Rows(k).EntireRow.Delete
Else
End If
Next k
End Sub
Thanks!
Some issues:
When you delete a row, and k increases, you actually skip a row, which you don't check. So, better go downwards with k to avoid this problem.
The way you compare against ASCII values has wrong syntax, as you need to explicitly specify a value after and immediately before each >= and <= operator. But instead of giving a correction (which would be long), I'll suggest a shorter syntax:
Checking for a letter can be done in a more readable way, which does not require the knowledge of ASCII codes. Simply check if the first character is different when put in upper case than when put in lower case. If so, it is a letter.
You are missing the Then keyword at the end of the If line;
Code:
Sub DeleteLetterRows()
Dim k as integer
Dim l as String
For k = 100 To 2 Step -1
l = Left(ActiveSheet.Range("A" & k).value, 1)
If UCase(l) <> LCase(l) Then
Rows(k).EntireRow.Delete
End If
Next k
End Sub
To check the first character of your string you use the function Left().
The easiest way to find out if is not a number is the function isNumeric().
Put together you will get
Sub DeleteLetterRows()
Dim k as integer
Dim test As String
For k = 2 To 100
test = Left(ActiveSheet.Range("A" & k).value,1)
If isNumeric(test) = False then
Rows(k).EntireRow.Delete
Else
End If
Next k
End Sub
I'm running a search query that pulls the search string from one text box, then searches a listbox for the string and displays the results in a second listbox. I would like to define the number of items that it returns based on a second text box. So far I am able to get all list items with be given string to show in the second box. But I have yet to get it to limit the search to 1 item etc. The functional code I've used to show all results is:
Private Sub btnGo_Click(sender As Object, e As EventArgs) Handles btnGo.Click
lstResults.Items.Clear()
If txtSearch.Text.Length > 0 Then
For index As Integer = 0 To lstCountries.Items.Count - 1
Dim txt = lstCountries.Items(index).ToString()
If txt.StartsWith(txtSearch.Text, StringComparison.CurrentCultureIgnoreCase) Then
lstResults.Items.Add(txt)
End If
Next
End If
I've tried using while txtnumber.text > 1 then ahead of this but seem to have created a loop. Any ideas as to what I'm missing?
The datasource is going to have the final say on how many results there are. If the user specifies 3 and there are only 2 in the source, thats all you will get. Something like this will move the results from one to the other until the max is found:
Dim Max as integer = Convert.Toint32(txtNumber.Text)
Dim Count as integer = 0
lstResults.Items.Clear()
For index As Integer = 0 To lstCountries.Items.Count - 1
if lstCountries.Items(index).StartsWith(txtSearch.Text, StringComparison.CurrentCultureIgnoreCase) Then
lstResults.Items.Add(lstCountries.Items(index))
count += 1
end if
' exit the loop if we found enough
If count>= Max Then
Exit For
End If
Next
If the listbox just contains text (strings) then you do not need the ToString: lstCountries.Items(index).StartsWith(strSearch). Basically, you need to exit the loop once the user desired number have been found OR if you run out of data...if I understood right. while txtnumber.text > 1 would not work because textboxes contain strings not numerics (23 is not the same as "23").
The LINQ extensions would work well here as well:
lstResults.Items.AddRange((From item In lstCountries.Items
Let strItem As String = item.ToString
Where strItem.StartsWith(txtSearch.Text, StringComparison.CurrentCultureIgnoreCase)
Select strItem).Take(Integer.Parse(txtnumber.Text)).ToArray)
This assumes that all your data has already been validated.
I am trying to work with taking in and parsing CSV files. Right now I have it taking in and producing something like this:
The program loads the csv and copies the data into an array as such:
ReDim strarray(num_rows, num_cols)
For x = 0 To num_rows
strline = strlines(x).Split(",")
For y = 0 To num_cols
strarray(x, y) = strline(y)
Next
Next
The CSV file data is very basic formatted with two columns and x number of rows:
212, 343
324, 232
etc. I guess my main problem is trying to perform calculations to all values in a specific column. To start I am just trying to figure out how to isolate the columns and found that by using MsgBox(strarray(x, num_cols)) it will msgbox everything in the second column twice. I just want to try and understand how I can perform a basic calculation like multiply every value in the first column by 2 and every value in the second column one by 3.
To start with: In VB arrays go from 0 to number of items minus 1. However you will have specify the maximum index, not the size:
Dim x As String() = new String(N-1) 'Where N is the number of items.
Dim y As String() = new String(MAX) 'Where MAX is the highest index.
And you have integer numbers. So you would have to declare:
Dim matrix As Integer(,) = new Integer(num_rows-1, num_cols-1)
And then fill it with:
For row As Integer = 0 To num_rows-1
Dim strline As String() = strlines(row).Split(",")
For col As Integer = 0 To num_cols-1
matrix(row, col) = Integer.Parse(strline(col))
Next
Next
Example calculation:
For row As Integer = 0 To num_rows-1
matrix(row,0) *= 2
matrix(row,1) *= 3
Next
I have the following code to generate combinations of string for a small list and would like to adapt this for a large list of over 300 string words.Can anyone suggest how to alter this code or to use a different method.
Public Class combinations
Public Shared Sub main()
Dim myAnimals As String = "cat dog horse ape hen mouse"
Dim myAnimalCombinations As String() = BuildCombinations(myAnimals)
For Each combination As String In myAnimalCombinations
''//Look on the Output Tab for the results!
Console.WriteLine("(" & combination & ")")
Next combination
Console.ReadLine()
End Sub
Public Shared Function BuildCombinations(ByVal inputString As String) As String()
''//Separate the sentence into useable words.
Dim wordsArray As String() = inputString.Split(" ".ToCharArray)
''//A plase to store the results as we build them
Dim returnArray() As String = New String() {""}
''//The 'combination level' that we're up to
Dim wordDistance As Integer = 1
''//Go through all the combination levels...
For wordDistance = 1 To wordsArray.GetUpperBound(0)
''//Go through all the words at this combination level...
For wordIndex As Integer = 0 To wordsArray.GetUpperBound(0) - wordDistance
''//Get the first word of this combination level
Dim combination As New System.Text.StringBuilder(wordsArray(wordIndex))
''//And all all the remaining words a this combination level
For combinationIndex As Integer = 1 To wordDistance
combination.Append(" " & wordsArray(wordIndex + combinationIndex))
Next combinationIndex
''//Add this combination to the results
returnArray(returnArray.GetUpperBound(0)) = combination.ToString
''//Add a new row to the results, ready for the next combination
ReDim Preserve returnArray(returnArray.GetUpperBound(0) + 1)
Next wordIndex
Next wordDistance
''//Get rid of the last, blank row.
ReDim Preserve returnArray(returnArray.GetUpperBound(0) - 1)
''//Return combinations to the calling method.
Return returnArray
End Function
End Class
'
CHANGES//
For wordDistance = 1 To inputList.Count.ToString / 2
Dim count = inputList.Count.ToString
'Go through all the words at this combination level...
For wordIndex As Integer = 0 To inputList.Count.ToString - wordDistance
'Get the first word of this combination level
combination.Add(inputList.Item(wordIndex))
'And all all the remaining words a this combination level
For combinationIndex As Integer = 1 To wordDistance
combination.Add(" " & inputList.Item(wordIndex + combinationIndex))
Next combinationIndex
'Add this combination to the results
If Not wordsList.Contains(combination) Then
wordsList.Add(combination.ToString)
End If
'Add a new row to the results, ready for the next combination
'ReDim Preserve returnArray(returnArray.GetUpperBound(0) + 1)
Next wordIndex
Next wordDistance
One obvious thing in your code is the usage of ReDim Preserve. That can be quite a slow operation since I think it copies the whole array into a new array every time the size is changed, and since you're doing that inside loops I assume that could be a significant issue.
The simplest way of fixing that is to stop using those kinds of arrays and instead use List with it's Add method.
I want to make sure I understand what you are trying to do first. Your problem seems to be:
Given a list of strings,
Return every possible combination of n items from the list,
where n = 2 to length of list
For example, in a list of 5 strings, you would want all combinations of 2 strings, of 3 strings, of 4 strings, and of 5 strings.
If that is an accurate statement of your problem, there is one glaring issue to point out. The number of items you will be generating is on the order of 2 ^ (length of list). This means that trying to generate all combinations of 300 items will never be fast no matter what. Also, for any but the tiniest of lists, you will need to generate items lazily or you will run out of memory.
If you do not want all combinations of all lengths, you may want to clarify your question to better state your desired goal.