Variables losing their value - mysql

I have the following vbscript code:
hemisphereConnectionString = "Driver={MySQL ODBC 5.1 Driver};" & _
"Server=" & hemisphereServer & ";" & _
"Database=" & hemisphereDatabase & ";" & _
"User=" & hemisphereUsername & ";" & _
"Password=" & hemispherePassword & ";"
Set hemisphereConnection = CreateObject("adodb.connection")
hemisphereConnection.Open(hemisphereConnectionString)
hem_sql = "SELECT * FROM hei_vision_update WHERE id IN (SELECT MAX(id) FROM hei_vision_update WHERE done = 'N' GROUP BY name)"
Set hemisphereResult = hemisphereConnection.Execute(hem_sql)
if hemisphereResult.EOF = false then
hemisphereResult.MoveFirst()
end if
msgbox isnull(hemisphereResult("home_publish").value)
msgbox hemisphereResult("home_publish").value
It is part of a much larger script (too big to post here but these are the key lines)
My message boxes display false (ie the field has a value that is not null) and the next message box crashes saying "Invalid use of Null"
Anyone have any Ideas??
I have modified my code to the above, This is all of it (except the server and password details). There are no OERN/OEG0 lines now. The row I am getting from the database has a 'Y' in the home_publish field, hence the first message box displaying false is correct. Just the second one displaying "Invalid use of Null" is the mystery. I am beginning to wonder if there is an issue with the MySQL Driver?
Now this is getting silly:
I changed the last 2 lines to these 3:
msgbox hemisphereResult("home_publish").value
msgbox isnull(hemisphereResult("home_publish").value)
msgbox hemisphereResult("home_publish").value
The first message box displays my value 'Y'.
Now the second message box displays true (which it obviously isn't).
And finally my third message box gives my "Invalid use of null" error.
Anyone else ever experienced variables losing their value just because you have used them?

If hemisphereResult is ADODB.Recordset, then hemisphereResult("home_publish") is ADODB.Field, at which point the following happens.
IsNull does not try to further investigate the passed object and returns False because the field itself exists as an object in the recordset.
MsgBox, on contrary, cannot do a meaningful thing to an object, so it calls the default property of that object (the Field object) in order to display it. The default property is .Value, and that is Null.
So despite the arguments to IsNull and MsgBox look the same in code, they are not actually the same.
You might want to be explicit in your demands:
msgbox isnull(hemisphereResult("home_publish").value)
While the above is true, you might have been affected by a MySQL bug too (44831, 42385 etc.)
The suggested workaround is to use client-side cursor:
set hemisphereResult = CreateObject("ADODB.Recordset")
hemisphereResult.CursorLocation = 3 'adUseClient
hemisphereResult.open "select ...", hemisphereConnection

Related

Setting Validation rules to multiple fields using VBA code returns error 3309 (too large)

I would like to ask you for help with (edited) VBA code I found while searching for solution. My goal is to add validation rule to multiple field of table at once by VBA code. I have to use VBA code because there is so many fields and manual input would be insane.
Validation rule: NOT LIKE "*"+Chr(10)+"*" OR "*"+Chr(13)+"*" OR "*"+Chr(9)+"*"
(user can't save "enter", "ctrl+enter" and "tabulator")
For using this rule in VBA function the syntax is quite different but input to MS Access is correct.
My VBA code (not directly my, I found it and edit to my needs)
Public Function SetFieldValidation()
Dim dbs As DAO.Database
Dim tdf As DAO.TableDef
Dim fld As DAO.Field
Dim strValidRule As String
Dim strValidText As String
Dim bytNumOfFields As Byte
strValidRule = "NOT LIKE " & Chr(34) & "*" & Chr(34) & "+Chr(10)+" & Chr(34) & "*" & Chr(34) & " OR " & Chr(34) & "*" & Chr(34) & "+Chr(13)+" & Chr(34) & "*" & Chr(34) & " OR " & Chr(34) & "*" & Chr(34) & "+Chr(9)+" & Chr(34) & "*" & Chr(34)
strValidText = "Some error msg"
Set dbs = CurrentDb
Set tdf = dbs.TableDefs("Table_Name")
For bytNumOfFields = 0 To tdf.Fields.Count - 1
With tdf.Fields(bytNumOfFields)
If .Name <> "Record ID" Then
.ValidationRule = strValidRule
.ValidationText = strValidText
End If
End With
Next
End Function
In the past this script works with rule NOT LIKE "*"+Chr(10)+"*" OR "*"+Chr(13)+"*".
Than tried to add OR "*"+Chr(9)+"*".
Since this modification the MS Access (VBA) returns error: Property value is too large. (Error 3309) while I run the script. When I tried return to previous version of script without +Chr(9)+, the error still remains (even I succesfully used this script in the past and validation rules are set in another tables).
I'm really beginer in VBA, honestly I only need to setup this rule to all field of all tables. Can someone experienced tell me what's wrong in the code?
Thank you very much.
I suggest not using Chr(). Since Chr will always return the same value for a particular number, e.g. Chr(65) always returns A, I don't think you need to use the function to get the value you want. So try setting your strValidRule as one long static string with the characters returned by the Chr() functions hard coded.
I did a research and probably the problem is somewhere else - looks like error in table design of specific table.
1.) First test: At first I tried to debug strValidRule string and compare two approaches for string (my and with quotes as #Rominus advised). The results are same but quoString is smoother approach. Than I run script (tried both approaches). Error msg said 'Property Value Too Large' error 3309 and the old valid rules remains in table design unchanged (rules were set in the past and remains).
Sub teststring()
chrString = "chrString: NOT LIKE " & Chr(34) & "*" & Chr(34) & " +Chr(10)+ " & Chr(34) & "*" & Chr(34) & " OR " & Chr(34) & "*" & Chr(34) & " +Chr(13)+ " & Chr(34) & "*" & Chr(34)
Debug.Print chrString
quoString = "quoString: NOT LIKE ""*"" +Chr(10)+ ""*"" OR ""*"" +Chr(13)+ ""*"""
Debug.Print quoString
End Sub
2.) Second test: From my script above I firstly 'commented' values of strValidRule and strValidText by ' and add empty values "". Script run without error msg and added empty values.
Than I 'uncommented' the values and run script with values mentioned above (quoString approach and some msg for strValidText). Scritp run with error msg 'Property Value Too Large' error 3309. BUT, when I checked table design, the valid rules were properly set and working even the error msg popped up.
3.) Third test: I tried to use script in another table and run it without previously adding empty values described in step 2. (because in table were set old valid rules too). Script successfully overwrote old valid rules by new ones without msg of error 3309.
So, I found the way how to set valid rules but there is still some bug that shows error msg in specific table. Don't know how to fix it but I hope it haven't affect of my main goal (setting new working valid rules).

Syntax issues when using string variables in DLOOKUP function in VBA for Access

I am trying to teach myself VBA for Access and am having some issues with the syntax for using text variables in a DLOOKUP function.
I am attempting to loop through a recordset one record at a time to see if two separate text fields from my recordset exist in the same two fields in a separate access table. If they do exist in the table, then I want to create an error message and display a message stating record exists already
Dim str1 As String
Set rst = db.OpenRecordset("temptbl")
Do Until rst.EOF
If Not IsNull(DLookup("Entry_Number" and "HTS_Line", "PO_Payment",
("Entry_Number= '" & rst!Entry_Number & "'") and ("HTS_Line= '" &
rst!HTS_Line & "'"))) Then
str1 = MsgBox("Entry number "" & rst!Entry_Number & "" already exists in
the PO_Payment table. Please investigate.", vbOKOnly)
Exit Do
rst.Close
DoCmd.DeleteObject acTable, "temptbl"
All fields are data type text but I am receiving a code 13 type mismatch error and cannot understand why. Can anyone help please?
DLookup("Entry_Number" and "HTS_Line", "PO_Payment", ...
The first parameter is invalid. It must be a single string, containing a column name or an expression.
E.g.
DLookup("Entry_Number", "PO_Payment", ...
or
DLookup("[Entry_Number] & ', ' & [HTS_Line]", "PO_Payment", ...

Setting and moving to a bookmark

I have an error message on a form that checks for an existing SSN on the BeforeUpdate event of a text box. If it already exists in the database, the user is given a message box to this effect, and has the option to go to the existing record. I'm using this example code here. My code is below.
Private Sub txtSocialSecurityNumber_BeforeUpdate(Cancel As Integer)
'check for existing SSN
Dim SSN As String
Dim strLinkCriteria As String
Dim rsc As Recordset
Set rsc = Me.RecordsetClone
SSN = Me.txtSocialSecurityNumber.Value
strLinkCriteria = "[SocialSecurityNumber] = " & "'" & SSN & "'"
'look for duplicates
If DCount("SocialSecurityNumber", "Person", LinkCriteria) > 0 Then
'Undo duplicate entry
Me.Undo
'error message
intResponse = MsgBox("Social Security Number " & SSN & " already exists in database." & _
vbCrLf & vbCrLf & "Would you like to view the record?", vbYesNo, "Duplicate SSN")
If intResponse = vbYes Then
'go to record
rsc.FindFirst strLinkCriteria
Me.Bookmark = rsc.Bookmark
ElseIf intResponse = vbNo Then
Exit Sub
End If
End If
Set rsc = Nothing
End Sub
According to this code, and several other examples I have looked up, it seems like I'm doing everything right, but I must not be because when I try to run the code and go to the existing record, I get the error "Run-time error '424': Object Required". When I debug, the row rst.FindFirst strLinkCriteria is highlighted, and hovering over it gives me the text strLinkCriteria = "[SocialSecurityNumber] = '123456789'" (123456789 is a known sample SSN in my database). Thank you to Sergey S. for pointing out the spelling error that fixed this section.
When I tell the message box to go to the record with the existing SSN, it gives me Run-time error '3021': No current record. Debug highlights the line Me.Bookmark = rsc.Bookmark with the message rsc.Bookmark = <No current record.>. So it sounds like I'm not assigning the bookmark correctly.
I've never used bookmarks before, so I'm not really sure what I'm doing wrong here. Any help would be appreciated.
You declared rsc, but used rst.
Change your code to
rsc.FindFirst strLinkCriteria
And I'd recommend always use Option Explicit in every module (default can be changed on options), otherwise you'll face with such kind strange errors. With this option the typo would be found by compiller, not at runtime.

how to limit the characters in access to more than 255

How to limit the characters in access to more than 255? for example, I want it the memo or text box to limit it to max 300 characters.
In Access 2010
If you want to limit a memo field in a table to no more than 300 characters, open the table in design view and add this as the field's Validation Rule property.
Len([memo_field])<301
Substitute your field's name for memo_field. You can also add a Validation Text property to display a more user-friendly message when the rule is violated. With no Validation Text, that rule would produce this message ... which might not be very clear to a user:
*One or more values are prohibited by the validation rule 'Len([memo_field])<301' set for 'YourTableName.memo_field'. Enter a value that the expression for this field can accept.*
You also mentioned a text box. If it is a text box bound to a memo field, you can validate the character length in the text box's Before Update event. If the text box is named txtMemo_field:
Private Sub txtMemo_field_BeforeUpdate(Cancel As Integer)
If Len(Me.txtMemo_field) > 300 Then
MsgBox "Please limit data to maximum of 300 characters."
Cancel = True
End If
End Sub
After the message box, the cursor will be still located within the text box, and the user will not be allowed to move to another form field without supplying an acceptable value for txtMemo_field.
Just to address a point in #HansUp's answer:
Is Null Or Len([memo_field])<301 ... If you don't want to allow
Nulls, drop the "Is Null Or" part.
There is no need to explicitly test for nulls in a constraint. A constraint doesn't have to evaluate TRUE for it to be satisfied.
If the Access database engine (ACE, Jet, whatever) actually had a spec it would read like this:
A table constraint is satisfied if and only if the specified
search condition is not false for any row of a table.
According to three-valued logic required to handle nulls, the search condition LEN(NULL) < 301 evaluates to UNKNOWN and the table constraint would be satisfied (because UNKNOWN is not FALSE).
However, Access has no such spec, so we must test and see that the above assertions are indeed true (simply copy and paste into any VBA module, no references required, creates a mew blank mdb in the user's temp folder, then creates table, Validation Rule -- without the explicit test for null -- then attempts to add a null with success, Q.E.D.):
Sub WhyTestIsNull()
On Error Resume Next
Kill Environ$("temp") & "\DropMe.mdb"
On Error GoTo 0
Dim cat
Set cat = CreateObject("ADOX.Catalog")
With cat
.Create _
"Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & _
Environ$("temp") & "\DropMe.mdb"
With .ActiveConnection
Dim Sql As String
Sql = _
"CREATE TABLE Test (" & _
" ID INTEGER NOT NULL UNIQUE, " & _
" memo_field MEMO" & _
");"
.Execute Sql
End With
' Create Validation Rules
Dim jeng
Set jeng = CreateObject("JRO.JetEngine")
jeng.RefreshCache .ActiveConnection
.Tables("Test").Columns("memo_field") _
.Properties("Jet OLEDB:Column Validation Rule").Value = _
"LEN(memo_field) BETWEEN 1 AND 300"
jeng.RefreshCache .ActiveConnection
Sql = "INSERT INTO Test (ID, memo_field) VALUES (1, NULL);"
.ActiveConnection.Execute Sql
Sql = "SELECT * FROM Test;"
Dim rs
Set rs = .ActiveConnection.Execute(Sql)
MsgBox rs.GetString(2, , , , "<NULL>")
Set .ActiveConnection = Nothing
End With
End Sub
Change its Data type to Memo.
max field size of text field
Regards

How can I check for null values in Access?

I am new to Access. I have a table full of records. I want to write a function to check if any id is null or empty. If so, I want to update it with xxxxx.
The check for id must be run through all tables in a database.
Can anyone provide some sample code?
I'm not sure if you are going to be able to find all tables in the database with Access SQL. Instead, you might want to write up some VBA to loop through the tables and generate some SQL for each table. Something along the lines of:
update TABLE set FIELD = 'xxxxxx' where ID is null
Check out the Nz() function. It leaves fields unaltered unless they're null, when it replaces them by whatever you specify.
For reasonable numbers and sizes of tables, it can be quicker to just
open them
sort by each field in turn
inspect for null values and replace manually
It's good practice to find out where the nulls are coming from and stop them - give fields default values, use Nz() on inputs. And have your code handle any nulls that slip through the net.
I'm calling it the UpdateFieldWhereNull Function, and shown is a Subroutine which calls it (adapted from http://www.aislebyaisle.com/access/vba_backend_code.htm)
It updates all tables in the DbPath parameter (not tested, handle with care):
Function UpdateFieldWhereNull(DbPath As String, fieldName as String, newFieldValue as String) As Boolean
'This links to all the tables that reside in DbPath,
' whether or not they already reside in this database.
'This works when linking to an Access .mdb file, not to ODBC.
'This keeps the same table name on the front end as on the back end.
Dim rs As Recordset
On Error Resume Next
'get tables in back end database
Set rs = CurrentDb.OpenRecordset("SELECT Name " & _
"FROM MSysObjects IN '" & DbPath & "' " & _
"WHERE Type=1 AND Flags=0")
If Err <> 0 Then Exit Function
'update field in tables
While Not rs.EOF
If DbPath <> Nz(DLookup("Database", "MSysObjects", "Name='" & rs!Name & "' And Type=6")) Then
'UPDATE the field with new value if null
DoCmd.RunSQL "UPDATE " & acTable & " SET [" & fieldName & "] = '" & newFieldValue & "' WHERE [" & fieldName & "] IS NULL"
End If
rs.MoveNext
Wend
rs.Close
UpdateFieldWhereNull = True
End Function
Sub CallUpdateFieldWhereNull()
Dim Result As Boolean
'Sample call:
Result = UpdateFieldWhereNull("C:\Program Files\Microsoft Office\Office\Samples\Northwind.mdb", "ID", "xxxxxx")
Debug.Print Result
End Sub