VBA For each character and group characters - string

I have been working on a project which is getting a serial number in the context of "J39303", But sometimes there are multiple serials but every time I can guarantee each serial will be 6 letters long, so for example,
J848407888488393 - here is 3 serials just without the J as the start, I want to be able to split it up into 3 separate values, J84840, 78884, 88393,
I have looked at right, mid and left but because the position changes I cannot use these, I am now looking at a For loop to group each 5 characters but have had no luck,
Could someone post me in the right direction,
Thanks!!

This should do it:
Sub mysplit()
Const SNLength As Integer = 5
Dim SNs As String
SNs = "J848407888488393"
Dim SerialNumber As String
Dim index As Integer
If Left(SNs, 1) = "J" Then SNs = Mid(SNs, 2)
index = 1
Do While index < Len(SNs)
SerialNumber = Mid(SNs, index, SNLength)
MsgBox "J" + SerialNumber
index = index + SNLength
Loop
End Sub

Related

generate unique ID in VBA (particular format)

I want to write VBA script and add it to the button to get an random unique ID.
The sample format:
F-B829IB-BKC1
F-QLM9I4-EFCY
It should start with "F" ; "-" ; random 6 digits/letters ; "dash" ; random 4 digits/letters
Thanks in advance for your assistance.
Here is a function that you might be able to apply to your needs:
Function RandID() As String
Dim pool As String
Dim id As String
Dim i As Long, n As Long
pool = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
n = Len(pool)
id = "F-"
For i = 1 To 11
If i = 7 Then
id = id & "-"
Else
id = id & Mid(pool, Application.WorksheetFunction.RandBetween(1, n), 1)
End If
Next i
RandID = id
End Function
Typical output: F-I8FTLX-3E81.
These IDs are on the short side. Uniqueness isn't guaranteed, especially if a large number of IDs are to be generated. The total number of IDs is 36^10, so you are probably safe for small-scale use.

vb.net - is it possible to output the first character from a string for monday and then the next character for tuesday (and so on)?

i have a string containing special characters ('★☆☽☾☁') and i would like to have ★ printed out for monday, ☆ for tuesday, ☽ for wednesday, ☾ for thursday, and ☁ for friday. i apologize since i am very new to vb.net so i have only very basic knowledge about it. i have already tried this:
Dim today As Date = Date.Today
Dim dayIndex As Integer = today.DayOfWeek
Dim specialcharacters() As Char = "★☆☽☾☁"
If dayIndex < DayOfWeek.Monday Then
txtRandomCharacter.Text = specialcharacters
End If
i would be extremely grateful if anyone could help, thank you!
How's this?
Const specialcharacters() As Char = "★☆☽☾☁"
Dim today As Date = Date.Today
Dim dayIndex As Integer = today.DayOfWeek
If dayIndex >= DayOfWeek.Monday andalso dayIndex <= DayOfWeek.Friday Then
txtRandomCharacter.Text = specialcharacters(dayIndex - dayOfWeek.Monday)
End If
It works because the value of DayOfWeek.Monday through DayOfWeek.Friday are sequential.
(Re-edit to correct my previous error of using VBA instead of VB.net)
Yes. Noting that you only have 5 Char in your array (specialcharacters()) I assume you only want to mark Monday to Friday. However, the answer to this question can be extended to cover all week. Using your original code as the base:
Dim txtRandomCharacter As Char = ""
Dim specialcharacters() As Char = "★☆☽☾☁"
Dim today As Date = Date.Today
Dim dayIndex As Integer = today.DayOfWeek
If (dayIndex - 1) <= UBound(specialcharacters) Then
txtRandomCharacter = specialcharacters(dayIndex - 1)
End If
However, note the mental gymnastics required in dealing with 0-based arrays.
Dim dayIndex As Integer = Weekday(today,vbMonday) is also valid code.
Explanation for Weekday can be found at http://www.excelfunctions.net/vba-weekday-function.html.
specialcharacters is an array, not a string, so that you can access the array element directly. I have used the UBound function so that you don't accidently get an array out of bounds error by calling a subscript (dayIndex) that is higher than your array is long.
Another option is to use the Mid or Substr function with strings. In this example I have also concatenated some code for brevity.
Dim txtRandomCharacter As String = ""
Const specialcharacters As String = "★☆☽☾☁"
Dim dayIndex As Integer = Date.Today.DayOfWeek ' - DayOfWeek.vbMonday + 1
txtRandomCharacter = If(dayIndex >= 0 And dayIndex <= Len(specialcharacters), specialcharacters.Substring(dayIndex - 1, 1), "X")
The 'X' option in the IIF statement was my addition for testing. You can also use "". Unfortunately, the Substr function in VB.Net is a little less tolerant than the Mid function, hence the additional checks on valid values for dayIndex. And Substr is 0-based.
Using the Mid function, which is tolerant of indexes > length of the string but must be > 0 (hence the If statement):
Dim txtRandomCharacter As String = ""
Const specialcharacters As String = "★☆☽☾☁"
Dim dayIndex As Integer = Date.Today.DayOfWeek ' - DayOfWeek.vbMonday + 1
txtRandomCharacter = Mid(specialcharacters, If(dayIndex > 0, dayIndex, Len(specialcharacters) + 1), 1)
Check your Option Base to see if your arrays start by default at 0 or 1. specialcharacters() could be ranging from 0-4 or 1-5 depending on this setting - which means is may or may not align with the Weekday function which is always in the range 1-7 (or the DayofWeek function which ranges from 0 to 6).
The key point is to understand the difference between a string and an array of characters.
With an array of characters - use array subscripts to select the right member. Check to ensure you are not passing an index that is out of bounds for the array.
With a string, use a Mid or Substr function to get the character from the string. Check to ensure you are not passing an index that is out of bounds.
The other point to recognise is to understand how the days of the week are enumerated. The MSDN reference site only notes the enumeration and does not provide an equivalent integer - the IDE provides some more information. This is important to understand if your counting starts from 0 or 1, and whether you must adjust your index to address this.

VB.NET Get Number Position Of Char In String (Index Of)

im having a hard time getting a function working. I need to search message.text for each "," found, for each "," found I need to get the number position of where the "," is located in the string. For example: 23232,111,02020332,12 it would return 6/10/19 where the "," are located (index of). My code finds the first index of the first , but then just repeats 6 6 6 6 over, any help would be appreciated thanks.
Heres my code:
For Each i As Char In message.Text
If message.Text.Contains(",") Then
Dim data As String = message.Text
Dim index As Integer = System.Text.RegularExpressions.Regex.Match(data, ",").Index
commas.AppendText(index & " ")
End If
Next
You can try it this way; instantiate a Regex object and increment each time the position from which you start the matching (this possibility is not available with the static method Match).
Dim reg As New System.Text.RegularExpressions.Regex(",")
Dim Index As Integer = reg.Match(data).Index
Do While Index > 0
commas.AppendText(index & " ")
Index = reg.Match(data, Index + 1).Index
Loop
p.s the returned indices are zero-based.
Just use the Regex.Matches method
Dim message As String = "23232,111,02020332,12"
Dim result As String = ""
For Each m As Match In Regex.Matches(message, ",")
result &= m.Index + 1 & " "
Next
I should also add that indexes are 0 based (which is why +1 is added to m.Index). If you later need these values to point to the position of a particular comma, you may be off by 1 and could potentially try to access an index larger than the actual string.

Parsing a String in Excel VBA without Leaving Trailing Spaces?

I am currently working on an Excel spreadsheet capable of exporting data from the Yahoo Finance API for dynamic stock quote analysis. I am having problems properly parsing the values into my excel spreadsheet. The issue is that the last column of numeric values have a trailing space character, which prevents Excel from recognizing it as a number and formatting it in comma style.
Here is the function I use currently:
Function UpdateStockData(rawWebpageData As String)
Dim stockQuotes As Variant
Dim stockQuoteValues As Variant
Dim i As Integer
Dim j As Integer
stockQuotes = Split(rawWebpageData, vbLf)
For i = 0 To UBound(stockQuotes)
If InStr(stockQuotes(i), ",") > 0 Then
stockQuoteValues = Split(stockQuotes(i), ",")
For j = 0 To UBound(stockQuoteValues)
sheet.Cells(5 + i, 4 + j).Value = stockQuoteValues(j)
sheet.Cells(5 + i, 4 + j).Value = Trim(sheet.Cells(5 + i, 4 + j).Value)
Next j
End If
Next i
End Function
Here is some sample data:
43.99,44.375,41.97,42.62,30098498
573.37,577.11,568.01,573.64,1871694
16.03,16.14,15.93,16.17,25659400
128.54,129.56,128.32,129.36,31666340
126.32,126.68,125.68,126.27,1629499
105.57,106.00,104.78,106.35,4972937
82.58,83.21,82.20,83.37,6214421
27.89,27.9173,27.62,27.83,1003967
49.07,49.56,48.92,49.55,13870589
43.055,43.21,42.88,43.28,25748692
34.12,34.41,33.72,34.095,23005798
159.42,160.56,158.72,161.03,3633635
43.01,43.90,41.00,40.30,10075067
100.25,100.48,99.18,99.74,9179359
139.54,140.49,138.75,140.69,1311226
119.86,120.05,118.7828,120.20,2931459
42.50,42.98,42.47,42.95,16262994
78.02,78.99,77.66,78.99,1826464
89.87,91.35,89.86,91.02,1773576
15.84,15.98,15.76,15.99,78441600
69.50,70.2302,69.49,70.49,2343967
80.895,81.15,78.85,79.60,28126686
33.08,33.20,32.955,33.25,739726
83.08,83.80,82.34,83.16,4475302
64.72,64.90,64.27,64.27,5147320
35.64,41.85,35.40,40.78,15871339
83.08,83.80,82.34,83.16,4475302
22.93,23.099,22.71,23.10,5290225
18.47,19.00,18.30,18.98,71891
69.65,69.684,69.08,69.98,5992137
154.35,155.22,154.00,155.57,4476188
80.08,81.16,79.77,81.51,7731275
47.79,48.87,47.31,48.58,2219634
23.04,23.21,22.97,23.23,891504
114.76,115.47,114.25,116.07,3799034
80.63,81.56,80.56,81.91,6140957
25.66,25.77,25.47,25.86,31543764
87.18,87.96,86.93,87.62,13467554
58.31,58.795,57.61,58.255,5791024
174.62,175.78,174.41,176.15,1035588
84.35,85.24,84.21,85.16,7369986
42.03,42.25,41.69,41.98,3192667
34.19,34.49,34.01,34.57,15652895
101.65,102.12,101.17,102.34,8665474
7.88,8.01,7.84,7.88,10425638
62.13,62.17,61.3525,61.97,16626413
23.10,23.215,22.85,23.18,651929
The last value of each row of data above is where the problem occurs.
Check the value of the last char on the last iteration it might be a return char. You can use the left function to take what you want or replace.
It would be easier to answer if we I can see the value of rawWebpageData variable.
Check the cell format, you can try to set it to numeric if it is text.
If I was doing it I would debug the data and step through it to look for characters that i'm not checking.

Qualifier errors when attempting to debug, along with final lines -- help pls

Below is the code i have put together from various examples to try achieve my goal. Concept is to be dynamic and retrieve from survey sheet within my workbook, to be able to obtain the corresponding TVD for the MD
--Use while loop only to run code if there is a depth in Column B Present. Nested loop uses the difference between depths to calculate a gradient.
---The issue i'm having is getting past my first debug error "Invalid Qualifier".
----Lastly, any suggestions for how i would then return the TVD to Column A, relevant to the looked up MD, within the nested loop to maintain the row in which the MD was grabbed. Sorry for making this so wordy, been working on this for over 10hrs while at work.
http://www.wellog.com/tvd.htm
Sub MdtoTVD()
Dim MD1 As String, MD2 As Integer
Dim TVD1 As String, TVD2 As Integer
Dim Srng As Range 'Survey MD column
Dim MDrng As Range 'MdtoTVD MD column as range
Dim MDdiff As Integer ' Var to calculate difference of MD end from MD start
Dim TVDdiff As Integer ' Var to calculate difference of TVD end from TVD start
Dim TVDincr As Double ' var to use for stepping TVD
Dim MDrow As Integer
Dim i As Long
MDrng = Range("Surveys!B27:B215") 'range from the survey sheet within my report book
Srng = Range("Surveys!G27:G215") 'range from the survey sheet within my report book
Dim X As Integer
X = 2
While Not (IsEmpty(Sheets("MDtoTVD").Cells(X, 2).Value)) 'runs loop as long as there a MD depth to be looked up
Cells(X, 2) = MDrow 'assigns current row value to for MD input
MD1.Value = Application.WorksheetFunction.Index(Srng, Application.WorksheetFunction.Match(MDrow, MDrng, 1)) ' retrieves Start point for MD
MD2.Value = Application.WorksheetFunction.Index(Srng, Application.WorksheetFunction.Match(MDrow, MDrng, 1) + 1) 'retrieves end point for MD
TVD1.Value = Application.WorksheetFunction.Index(MDrng, Application.WorksheetFunction.Match(MDrow, Srng, 1)) 'retrieves start point for TVD
TVD2.Value = Application.WorksheetFunction.Index(MDrng, Application.WorksheetFunction.Match(MDrow, Srng, 1) + 1) 'retrieves end point for TVD
MDdiff.Value = (MD2 - MD1) 'assigns and calculates difference of MD end from MD start
TVDdiff.Value = (TVD2 - TD1) 'assigns and calculates difference of TVD end from TVD start
TVDincr.Value = MDdiff / TVDdiff 'Divides MD by TVD to get increment per foot
For i = 1 To MDdiff Step TVDincr 'set max loop run to amount of feet between survey points
Cells(X, 1).Value = TVD1 + i 'uses the loop to increment the TVD from start point
Next i
Wend
End Sub
I can see a number of problems with your code:
MD1, MD2, TVD1, TVD2 are all of type String. Also, MDdiff, TVDdiff and TVDIncr are all of type Integer. The property Value is not defined for a string or integer variable. Just remove the .Value from all of them and you won't get the "Invalid Qualifier" error.
After you do the above, the following lines will give another error about type mismatch:
MDdiff = (MD2 - MD1)
TVDdiff = (TVD2 - TD1)
because you're trying to subtract a string from another string and assign the result to an integer. Not sure what to advise there, you have to consider what you're trying to achieve and act accordingly. Maybe they shouldn't be strings in the first place? I don't know, up to you to determine that.
At the very least, you can cast strings to integers if you're really sure they're string representations of integers by doing CInt(string_var) or use CLng to convert to long. If the strings are not string representations of integers and you try to cast them to integers, you'll get a type mismatch error.
When you assign a value to a Range object, you need to use Set. So do:
Set MDrng = Range("Surveys!B27:B215")
Set Srng = Range("Surveys!G27:G215")
to correctly set the ranges.
Another problem is that you haven't assign a value to X but you use it as a cell index. By default, uninitialised numeric variables in VBA get assigned the value of 0, so doing .Cells(X, 2) will fail because row 0 is not a valid row index.
In this line:
TVDincr = MDdiff / TVDdiff
you're dividing two integers and you assign the result to another integer. Note that if the result of the division happens to be a decimal (like 3 / 2 = 1.5), your TVDincr integer will actually contain just 1, i.e. you lose some precision. I don't understand your code to know if it's ok or not, you have to judge for yourself, I'm pointing it out just in case you're not aware of that.
Also, if TVDdiff happens to be 0, then you'll get a "division by zero" error.
This line in your For loop:
Cells(X, 1).Value = TVD1 + i
will also generate an error, because you're trying to numerically add TVD1 (a string) and i (a long). Perhaps you're trying to concatenate the two, in which case you should replace + with &.
There's also a problem when calling the WorksheetFunctions, but I haven't been able to determine the cause. Probably if you fix the other errors then it'll be easier to understand what's going on, not sure though. You just have to investigate things a little bit too.

Resources