change credit card coding - vba

I have a mail merge VBA code of:
If GetField(oDS, "mCCNumber") <> "" Then
sCCNumber = Right(GetField(oDS, "mCCNumber"), Len(GetField(oDS, "mCCNumber")) - 12)
but now our CC #s are only 4 characters with no tokens, but some still come through with the 16 characters.
how do I change this code to add "OR" 3 characters (some are 3 and others 4).
also, I cannot comment this out to stop this portion

First, GetField(oDS, "mCCNumber") is being dereferenced 3 times in these two lines alone - pull it into its own local variable:
Dim ccNumberField As Field
Set ccNumberField = GetField(oDS, "mCCNumber")
Actually we're more interested in the field's contents. Your code is making an implicit default member call against the Field object - but a Field's default property is its Code:
A field's code is everything that's enclosed by the field characters ({ }) including the leading space and trailing space characters.
That means the string you're working with is longer than your code is expecting. I'd think you'd be more interested in the Text of the field's Result:
Dim ccNumberFieldValue As String
ccNumberFiedValue = ccNumberField.Result.Text
If ccNumberFieldValue <> "" Then
'...
Now, ccNumberFieldValue should hold the field's actual content. I'm not 100% clear from the OP exactly what that contains though. So I'm going to assume one of such:
Last 4 digits: **** **** **** 1234
Last 3 digits: **** **** **** *234
Woopsie, all 16 digits: 1234 1234 1234 1234
So the first thing to do is to grab the last 4; Right$ does that:
sCCNumber = Right$(ccNumberFiedValue, 4)
That leaves us with either:
1234
*234
From there you can use IsNumeric to determine if the entire substring is numeric (assuming there's a non-numeric padding character) - if it isn't, then you know you're looking at the 3-character variant:
If Not IsNumeric(sCCNumber) Then sCCNumber = Right$(sCCNumber, 3)

Related

Need to identify first character of my string (variable)

I have a string called Policynumber
I need to know if it begins with a 1 or a 2 so I can create an if statement for if it starts with 1 do something and if it starts with 2 to do something else.
I keep finding ways to do this for string text but not for a variable.
I have tried doing the following:
If policynumber Like "1*" Then
display.text = policynumber
End If
I am simply looking for possible ways to know what the first character is and therefore determine if it's a 1 or a 2. When I try using the variable name or even a textbox.text I get no result in the display textbox so I know it's not working.
I would use VBA's ASC() function for this purpose. This function returns the ASCII code of the first character of a string. ASCII for the character 1 is 49 and 2 is 50. Therefore ...
Dim PolicyNumber As String
Dim n As Integer
PolicNumber = "1ABC-45678910"
n = ASC(PolicyNumber)
MsgBox "Policy number starts with a " & Chr(n)
For testing the result you can use either If n = 49 Then or If Chr(n) = "1" Then.

Copying a specfic line within a cell into another cell

I have a spreadsheet that has multiple lines within a cell, all with line breaks.
e.g.
Name: a
Age: 1
University: 1
Degree: 3
Year: 3
I am looking to extract (in this example) the University infomation that is contained within the cell and copy it into another cell in another column.
There are about 1000 records in my document so to copy and paste by hand will be time consuming.
Any help will be appreciated
Cheers
Joe
You could do this with an Excel formula.
Assuming your data is in column A, and you want the extraction in column B, and assuming you put a title in row 1, you could do as in the following image:
(Note that I have a semi-colon in the formula as list separator, use comma instead)
The formula in B2 is:
=MID($A2, FIND(B$1, $A2) + LEN(B$1),
FIND(CHAR(10), $A2 & CHAR(10), FIND(B$1, $A2)) - FIND(B$1, $A2) - LEN(B$1))
The formula has some duplication; here are some of the parts explained:
FIND(B$1, $A2) returns the position of the title in the text
FIND(B$1, $A2) + LEN(B$1) returns the position of what follows that title in the text
FIND(CHAR(10), $A2 & CHAR(10), FIND(B$1, $A2)) returns the position of a newline character following the title, making sure that if none is present, a position beyond the string length is returned
As long as you put the column titles to whatever sub-string you are looking for, you can copy/drag the same formula to other columns and rows.
If there is a single break between each line, then in B1 enter:
=TRIM(MID(SUBSTITUTE($A1,CHAR(10),REPT(" ",999)),COLUMNS($A:C)*999-998,999))
This assumes that:
the university line is the third line
you want the entire line
I'm providing an answer even though you haven't provided what attempts you've made so far, which is how questions on this site usually work...but today I'm feeling generous :)
Use a combination of MID and FIND formulas, like the following:
=MID(A1,FIND("University",A1),FIND("Degree",A1)-FIND("University",A1)-2)
I put your example text in Cell A1 for my test, and it returned University: 1. This however will only work if University is always followed by Degree in the text strings.
The other method would be to replace the last part of your MID statement (the part asking for length to return) with the exact number of characters to return, which in this case would be 13, like the following:
=MID(A1,FIND("University",A1),13)
This assumes that the integer associated with University is always 1 character in length.
Either way, a combination of the above two formulas should get you what you need. VBA should not be necessary in this case.
Lines in a cell value are separated by the line feed character vbLf, so to extract the information out of the cell value you can use String-Functions Mid(...) and InStr(...):
Dim cellValue as String
Dim extracedValue as String
Dim keyWord as String
Dim posStart as Integer, posEnd as Integer
extractedValue = "" ' Not necessary, but I prefer initialized variables
cellValue = ActiveSheet.Cells(1,1).Value ' Put your cell here
keyWord = "University" ' Put your keyword here
posStart = InStr(1, cellValue, keyWord) ' Find keyword in the string
If (posStart > 0) Then
posEnd = InStr(posStart, cellValue, vbLf) ' Find next line feed after the keyword
If (posEnd > 0) Then
extractedValue = Mid(cellValue, posStart, posEnd - posStart) ' Extract the value
End If
End If
I haven't tested the code, but you should get the idea.

how to get each hexadecimal value present in the text box into an array?

In my application, the users may need to add hexadecimals in the textbox during run time and I would like to get each hexadecimal value in an array by removing the spaces if there are any.
For example, the data in the textbox is "ff 00 ff 1a ff 00". I could able to get each hexadecimal as an array with the help of split. But, now I am trying to remove all the spaces as some users may enter the hexadecimals without giving the space. For example, the user my enter as "ff 00 ff1a ff 00". So, in this case the third array contains "ff1a", which is not true. I know how to remove the spaces, but cannot able to figure out the way to get each hexadecimal into an array.
'Used to split the strings based on the spaces, which is not useful
'Dim extraData As String() = Split(TextBox8.Text, " ")
'Used to remove the spaces
Dim myString = TextBox8.Text.Replace(" ", "")
Any suggestion will be appreciated.
You can use something like:
Dim input As String = TextBox1.Text
Dim list As New List(Of String)
input = input.Replace(" ", "")
For i As Integer = 0 To input.Length - 1 Step 2
list.Add(input.Substring(i, 2))
Next
Dim array = list.ToArray()
Note - The length of the input (after removing spaces) must be even. Otherwise, it may throw an exception.
If I convert the method from C# to VB.NET given in this answer:
Public Function StringToByteArray(hex As [String]) As Byte()
Dim NumberChars As Integer = hex.Length
Dim bytes As Byte() = New Byte(NumberChars / 2 - 1) {}
For i As Integer = 0 To NumberChars - 1 Step 2
bytes(i / 2) = Convert.ToByte(hex.Substring(i, 2), 16)
Next
Return bytes
End Function
Then you can call it like this:
StringToByteArray(YourInputString.Replace(" ", ""))
This will return an array of bytes and will also validate the input because it will thrown an exception if invalid characters are used in the input (like non-hex characters).
I know you already have accepted an answer, however, I'd like to suggest another alternative. I'm assuming, based on the context of your question and the example that you provided, that your intention is to parse a list of bytes, where each byte is represented by a two digit hexadecimal value.
If you use regex to find your matches, it will be more powerful. For instance, you can easily ignore all white-space characters (e.g. tabs, new-lines) and you can easily validate the data to make sure that only properly formatted bytes are in the string (i.e. 00 - FF). For instance, you could do something like this:
Dim bytes As New List(Of String)()
Dim m As Match = Regex.Match(TextBox1.Text, "^\s*((?<byte>[a-fA-F0-9]{2})\s*)*$")
If m.Success Then
Dim g As Group = m.Groups("byte")
If g.Success Then
For Each c As Capture In g.Captures
bytes.Add(c.Value)
Next
End If
Else
MessageBox.Show("Input is not properly formatted")
End If
However, if the idea is to parse the actual byte values, you can do so using Byte.Parse, like this:
Dim bytes As New List(Of Byte)()
Dim m As Match = Regex.Match(TextBox1.Text, "^\s*((?<byte>[a-fA-F0-9]{2})\s*)*$")
If m.Success Then
Dim g As Group = m.Groups("byte")
If g.Success Then
For Each c As Capture In g.Captures
bytes.Add(Byte.Parse(c.Value, NumberStyles.HexNumber))
Next
End If
Else
MessageBox.Show("Input is not properly formatted")
End If
Both of those examples use the same regex pattern to find all of the hexadecimal bytes in the string. The pattern it uses is:
^\s*((?<byte>[a-fA-F0-9]{2})\s*)*$
Here's the meaning of the regex pattern:
$ - The match must start at the beginning of the string (i.e. no invalid text can come before the bytes)
\s* - Any number of white-space characters can come before the first byte
\s - Any white-space character
* - Zero or more times
((?<byte>[a-fA-F0-9]{2})\s*)* - Any number of bytes, each separated by any number of white-space characters
( - Begins the group so that we can later apply a kleene star to the whole group (which means the whole group can repeat any number of times)
(?<byte> - Begins another, inner group which is named "byte". It is given a name so that we can easily reference the values captured by the group in the VB code.
[a-fA-F0-9]{2} - A two-digit hexadecimal byte (i.e. 00 - FF)
[a-fA-F0-9] - Any character between a and f or between A and F or between 0 and 9
{2} - There must be exactly two characters matching that specification
) - Ends the group named "byte". Notice that this named-group only captures the two actual hexadecimal digits. It does not capture any of the white-space between the bytes.
\s* - There can be any number of white-space characters after a byte
) - The ends outer group which includes a byte and all of the white-space that comes after it
* - The aforementioned kleene star meaning that the outer-group can repeat any number of times
$ - The match must end at the ending of the string (i.e. no invalid text can come after the bytes)

while entering more than 10 digit numeric validation in grid view not working

I have a grid view ,,in grid view 5 th and 6 th column i have only enter numeric data,i mean mobile number and land number ,
i given code like this in gridview_cellvalidating event
If e.ColumnIndex = 5 Or e.ColumnIndex = 6 Then
Dim i As Integer
If Not String.IsNullOrEmpty(e.FormattedValue) AndAlso Not Integer.TryParse(Convert.ToString(e.FormattedValue), i) Then
e.Cancel = True
MsgBox("Please Enter Numeric")
Else
End If
End If
but this code is working if i enterd only 10 digit number,in 6 th column of datagrid view i have to enter country code also 'So i am giving number somthing like this: 971563158147.
this number is coming more than 10 digit,so this time showing message box("Please Enter Numeric")
how i can resolve this issue?
If you want to only allow all-numeric input up to, say, 12 characters, and don't actually care about parsing it as a number, you could use regular expressions. Pseudo-code:
Imports System.Text.RegularExpressions
Regex regex = new Regex(#"\d{12}");
If Not String.IsNullOrEmpty(e.FormattedValue) AndAlso Not regex.IsMatch(e.FormattedValue)
This will ensure that you get a non-empty input which is composed of exactly 12 digits. Now, if you wanted to allow, say, between 8 to 12 digits, you would just change the regex to:
Regex regex = new Regex(#"\d{8,12}");
To address your original query, 971563158147 is larger than the maximum value for Int32, so there will be overflow when parsing it. That's the source of your error.
You are running into the maximum value for an Integer when the input number is larger than 2,147,483,647.
You could instead use a regular expression to validate the input or use Int64.TryParse.
Check the MaxInputLength of the 6th cell, change it to required length if the field holds 10

VB determining values within a string

I am looking for assistance with my program. I have a user enter 6 digits; of these the input must be alpha-numeric. I have already done the TryParse method for the numbers, but I am looking for validation that the string contains an alpha.
I am aware you must use ASC but am unsure both on how to develop a range say Asc((Chr(65) <= Chr(90))) (between A-Z) and also to say (IF my input contains any of these values within the 6 characters, to return true. I keep getting an overload resolution and wish to know how to properly code so the variables are accurate.
This is a great place to use a regular expression
Dim input = ...
If Regex.IsMatch(input, "^\w+$") AndAlso input.Length = 6 Then
' It's a match
Else
' It's not a match
End If
This will match any string which consists only of letters that has length equal to 6
You can iterate through each char and check if it's a letter. If so, set a flag to true.
Dim containsAlpha Boolean = False
For i As Integer = 0 To input.Length - 1
If Char.IsLetter(input(i)) Then
containsAlpha = True
Exit For
End If
Next
Char.IsLetter will match Unicode alphabetic letters, so not just Latin A-Z (which may or may not be what you actually want).