I have a table linked to a form where a user enters an ISBN number. I'm checking to make sure the ISBN is valid. However, when I get to a point where I need to compare two numbers, I am incorrectly told that they do not match, when they definitely do match.
Private Sub isbn_BeforeUpdate(Cancel As Integer)
Dim isbn As String
Dim cleanIsbn As Double
Dim onlyIsbn As Double
Dim checkDigit As Integer
Dim legnth As Integer
length = 0
isbn = Forms!frmPubInfo!isbn.Value
' Strip out all hyphens
For i = 1 To Len(isbn)
Dim ch As String
ch = Mid(isbn, i, 1)
If IsNumeric(ch) Then
length = length + 1
Dim num As Integer
num = CInt(ch)
cleanIsbn = (cleanIsbn * 10) + num
End If
Next
' Check if 13 numbers
If length = 13 Then
Dim xBy3 As Boolean
Dim total As Integer
Dim calcCheckDigit As Integer
total = 0
xBy3 = False
' Calculate total amount
For j = 1 To 12
ch = Mid(cleanIsbn, j, 1)
If xBy3 = True Then
total = total + (ch * 3)
xBy3 = False
Else
total = total + ch
xBy3 = True
End If
Next
' Get calculated check digit
calcCheckDigit = 10 - (total Mod 10)
' Extract check digit
checkDigit = Mid(cleanIsbn, 13, 1)
' Debug output
MsgBox ("Actual CheckDigit: " & checkDigit & vbNewLine & _
"Calculated CheckDigit: " & calcCheckDigit)
' Check if check digit and calculated check digit match
If checkDigit <> calculatedCheckDigit Then
MsgBox ("checkDigit and calcCheckDigit are not the same")
Else
MsgBox ("They match! ISBN is good!")
End If
Else
' Display error
MsgBox ("Not enough numbers!")
End If
End Sub
When I get down to the 'Check if check digit and calculated check digit match', the If statement always says they don't match, even though the debug output above gives me the same two numbers.
I have tried:
Declaring the checkDigit variables as strings.
Casting the checkDigit variables as strings in the If Statement with CStr.
Casting the checkDigit variables as Integers in the If Statement with CInt.
I initially thought it was an issue with the data types, but if I'm casting them to the same type right as I'm comparing them, that can't be the issue, right?
This is all using Access 2013.
Man... I can't believe I didn't see this at first. I tested your code and got similar results as you. After looking at it closer I noticed that the if statement was wrong. In short you need to use Option Explicit and this error would have been caught. Option Explicit ensures that all variables are declared. In not an error is thrown.
You statement contains a null
If checkDigit <> calculatedCheckDigit Then
You dont have a variable called calculatedCheckDigit it should be calcCheckDigit.
If checkDigit <> calcCheckDigit Then
Just a side note: Your code for stripping out the hyphens obviously works but I offer this tweak.
' Dim as string since it is treated as one with Mid anyway.
' In practice Len didnt give accurate results while it was Double.
Dim cleanIsbn As String
' Strip out all hyphens
cleanIsbn = Replace(isbn, "-", "")
' Check if 13 numbers
If (Len(cleanIsbn) = 13) And IsNumeric(cleanIsbn) Then
' Process Stuff
Else
' Display error
MsgBox "Does not appear to be a valid ISBN value!"
End If
Take the isbn and just remove the hyphens with a replace. After that change if the result cleanIsbn is 13 characters long and numeric then you can assume its a good value to process.
ISBN Reference
I had to look it up but the math behind the ISBN numbers is located for reference here
Related
What I need (alphabetical numbering of rows-highlighted in bold(serial column)):
I have tried converting the output of rownumber function into string, But nothing seems to work as I don't have any idea.
Please help!
You can do this with a bit of custom code.
Go to the Report Properties, click the "Code" tab and paste the following code into the custom code window.
Public Function GetRowLetter(RowNum As Integer) As String
' stick the RowNum in a variable that we can reduce until it's zero
Dim r As Integer
Dim i As Integer
Dim s As String ' holds result
s = ""
r = RowNum
' we start at the right side so if the rownum is 28 we want to be back AB
' need to get 'B' first
Do While RowNum > 0
r = Int((RowNum - 1) / 26)
i = (RowNum - 1) Mod 26
s = Chr(i + 65) & s
RowNum = r
Loop
GetRowLetter = s
End Function
This will give "A" for 1, "B" for 2 etc, then it will give "AA" for 27, "AB" or 28 etc...
If you want to return lower case letters instead, swap the 65 for 98
In your report set the textbox value expression to
=Code.GetRowLetter(RowNumber("myDataSetName"))
swap out myDataSetName with the name of your dataset or scope you want to apply it to. Remember the dataset and scope names are case sensitive and must be surrounded by quotes ( " )
I am trying to add some data into 'List' form(exactly copy).
Below is my code.
Option Compare Database
Private Sub addToListSample_Click()
Dim introw As Integer
introw = ListSample.ListIndex + 1
ListSample.Column(0, introw) = TextP11.Value
ListSample.Column(1, introw) = TextP12.Value
ListSample.Column(2, introw) = TextP13.Value
ListSample.Column(3, introw) = TextP14.Value
ListSample.Column(4, introw) = TextP15.Value
ListSample.Column(5, introw) = TextP16.Value
ListSample.Column(6, introw) = TextP17.Value
End Sub
But when I execute it, I get following error.
"Run-time error '424' : Object required"
Why do I get this error? I think this is pretty easy code, but I don't know why this error keep annoying me....
Start by changing
introw = ListSample.ListIndex + 1
to
introw = Me.ListSample.ListIndex + 1
At some point you will probably also have to check that the listbox is actually selected or you will always get 0.
edit:
'add a row with hard-coded values:
'Dim introw As Integer
'introw = Me.lstEmpty.ListIndex + 1 '<-- not really needed when using AddItem.
'Me.lstEmpty.AddItem "value 1;value 2"
'or add a row using values from textboxes:
Me.ListSample.AddItem TextP11.Value & ";" & TextP12.Value & ";" & TextP13.Value
This will add values to one row, in different columns.
Your list box's Row Source Type will have to be set to Value List.
The Column Count will have to match the number of columns you're adding.
I'm comparing 2 variants to see if one is bigger than the other. Simple stuff right? But VBA is returning the completely wrong result. When I compare Variant1>Variant2, the statement will return true even when variant 1 is smaller than variant 2.
I cant help but think this has something to do with using Variants over Doubles, but it is unfortunately necessary as that value can sometimes be set to Null.
Dim max As Variant
Dim val1 As Variant
Dim val2 As Variant
...
max = .Fields("Max") 'These values are pulled from a recordset where the field is a double
...
val1 = .Fields("Val1")
val2 = .Fields("Val2")
...
'val1 = .001
'val2 = .001
'max = .002
If (val1 > max) Or (val2 > max) Then
outOfSpec = outOfSpec + Description + vbCrLf
End If
As it so happens I had val1 and val2 set to Text in the database. This is where the problem occurred as it was comparing a string and a double.
In one Short Text column of a table such data was stored "any_text_N" where N is some number specific for each row.
I need to replace N by N+1.
Could any one provide query to do it?
Assuming (1) the number is always the rightmost characters, and (2) there is an underscore preceding the number, you can create a Function to parse the number and return the incremented value (see below).
Then to test it, create a query like follows (MAKE SURE YOU TEST FIRST!!!):
SELECT Table2.MyText, resetnbr([MyText]) AS NewVal
FROM Table2
WHERE (((Table2.MyText) Is Not Null));
Then to update your data:
UPDATE Table2 SET Table2.MyText= resetnbr([MyText])
WHERE (((Table2.MyText) Is Not Null));
Public Function ResetNbr(strIn As String) As String
'Assumes: (1) Number in rightmost position of string; (2) underscore preceeds number
Dim iLen As Integer
Dim i As Integer
Dim sNbr As String
If strIn = "" Then
ResetNbr = strIn
Exit Function
End If
iLen = Len(strIn)
For i = iLen To 1 Step -1
If Mid(strIn, i, 1) = "_" Then
Exit For
End If
Next i
If i > 1 Then
sNbr = Mid(strIn, i + 1, 99)
sNbr = sNbr + 1
ResetNbr = left(strIn, i) & sNbr
Else
' No underscore found!
ResetNbr = strIn
End If
End Function
I have been trying to figure this error out for the past few days with no luck. I am hoping one of you would be able to help. I am getting "value used in formula of wrong data type.
Quick explanation:
convert functions like this one to its corresponding text (20054/18393)*100.0
the 5 digit numbers are Field IDs that refer to questions.
ID Question
20054 How many days of year do you work
18393 How many days of vacation do you get a year
The result I am trying to get to is (How many days of year do you work / How many days of vacation do you get a year) *100.0
It could be easily done manually if it was just a hand full. I have over 2600 formulas that need to be converted.
I created this function below which is resulting in the error mentioned in the title. Any assistance would be greatly appreciated
Here is my function
Function Test(sInput As String) As String
Dim i As Long
Dim num As String
Dim Text, a, str, shortname As String
For i = 1 To Len(sInput)
a = Mid(sInput, i, 1)
If IsNumeric(a) Then
num = num & a
Text = ""
Else
If a = "." Then
num = num & a
Else
'search for num value in second sheet short name
shortname = WorksheetFunction.VLookup(WorksheetFunction.Int(num), Worksheets("questionlist").Range("A3:F2537"), 5, False)
num = ""
End If
Text = shortname & a
shortname = ""
End If
str = str & Text
Next
Test = str
End Function
The error is raised because you are passing blank value to INT Function in the line
WorksheetFunction.VLookup(WorksheetFunction.Int(num), Worksheets("questionlist").Range("A3:F2537"), 5, False)
To reproduce the error Type =INT("") in any cell
To fix this handle blank values
Updated Answer:
Function Formula2Text(ByRef myCell As Range) As String
Dim QuestionId As Integer
Dim strInput As String
'Get Formula instead of values
strInput = myCell.FormulaR1C1
'Use Regex to Catch all ID's
Set Regex = CreateObject("VBScript.RegExp")
Set rnglookup = Worksheets("questionlist").Range("A3:F2537")
Regex.Global = True
Regex.Pattern = "\d+"
For Each Match In Regex.Execute(strInput)
'Skip if the ID is 100
If (Match.Value <> 100) Then QuestionId = Match.Value
'Lookup ID in the rnglookup,Make sure the Ids are sorted in asc in the questionlist sheet
Qntxt = Application.VLookup(QuestionId, rnglookup, 5, False)
If IsError(Qntxt) Then Qntxt = "Missing Lookup"
'Replace the ID with the lookup
strInput = Replace(strInput, QuestionId, Qntxt)
Next
Formula2Text = strInput
End Function
Usage:In the cell next to the formula use the function by referencing the formula
=Formula2Text(A1)