Change a column's Format to Percent using a SQL - sql

I have a query in VBA that Adds a few columns to a table. How can I change the format of the PercentSuccess column to Percent using SQL in VBA?
Here is the code I'm using to add the columns.
strSql5 = " Alter Table analyzedCopy3 " & _
"Add Column PercentSuccess Number, Success Number, prem_addr1 TEXT(50) "
DoCmd.SetWarnings False
DoCmd.RunSQL strSql5
DoCmd.SetWarnings True
I've tried to use Format() but I can't get it to work for changing what I need to change. It only seems to change the things like Number, Text and so on.

You cannot set the Format property using SQL but you can do it through additional VBA code. Also you should know that certain field properties do not actually exist until they are assigned a value of which the Format property is one of them. The code below first gets a reference to the field in question, creates a new Format property with the desired value, and then appends it to the fields definition. The Microsoft Access UI is misleading because it makes you think the property already exists.
Dim db As Database
Dim tdef As TableDef
Dim fdef As Field
Dim pdef As Property
Set db = CurrentDb()
Set tdef = db.TableDefs("analyzedCopy3")
Set fdef = tdef.Fields("PercentSuccess")
Set pdef = fdef.CreateProperty("Format", dbText, "Percent")
fdef.Properties.Append pdef
Finally this code only works if you use the DAO objects; you cannot set this property using ADO.

Related

How to reference textbox in a MS Access form in SQL

I need to find a way to make SQL pick up the data in a textbox on the form in MS Access. If there is any other way around this I'm sure I can do that as I have spent so much time on it already!
In a textbox on the form is where you write down the primary key your using then click submit. It would run the SQL, but the issue is I can't find how to get primary key in there. It's working as if I put it in '' then the whole SQL works. That's only if there is one choice but I want to be able to put loads of possible numbers in.
I have tried:
textbox.text, [forms]![form1]![textbox], form1.textbox,
Here's my current code:
Dim strQuery As String
strQuery = "UPDATE cwsmeriaid SET Pwyntiau = Pwyntiau + 1 WHERE Rhif_Yswiriant_Gwladol = Forms![frm_Archebiad]![rhifYswiriant]"
DoCmd.RunSQL strQuery
Don't enclose variables in quotes. Referencing form control is a variable. Concatenate variables.
Dim strQuery As String
strQuery = "UPDATE cwsmeriaid SET Pwyntiau = Pwyntiau + 1 WHERE Rhif_Yswiriant_Gwladol = " & Forms![frm_Archebiad]![rhifYswiriant]
DoCmd.RunSQL strQuery
If you want to avoid warning popups with action SQL, either turn warnings off then on with DoCmd.SetWarnings [True/False] or use:
CurrentDb.Execute strQuery

MS Access - SetFocus on multiple text boxes to check if data exists via SQL

The problem I'm facing:
I try to check if inserted text from multiple text boxes is already existing in a table before saving the records to avoid duplicates.
I created a form to enter new members and save them into a table. The key to avoid duplicates is to check the combination of given name, last name and birth date with existing records. (It's most likely that there won't be two person with all three criteria matching)
I have no problem to check the existence for only one text box by setting the focus on the desired box and use the SQL query IF EXISTS...
But since I would need to set focus on several text boxes(IMO) the problem occurs.
Is there a way to set focus on multiple text boxes?
The idea would be to use an IF EXISTS...AND EXISTS statement and I would need to implement the .SetFocus statement for each text box before checking its existence.
I hope you get my point and I would be glad if someone could share some knowledge. :)
Thanks in advance
There seems to be some missing information in order to find the best solution to your problem. so the below response will be based on assumptions as to how your form is working.
I'm assuming you are using an unbound form with unbound text boxes? if this is the case, then you must have a button that is the trigger for checking/adding this information to your table. lets say your command button is called "Save". You can use the following code without the need to .setfocus to any textbox.
Private Sub Save_Click()
Dim db as DAO.Database
Dim rst as DAO.Recordset
Dim strSQL as string
set db = currentdb 'This is the connection to the current database
'This is the SQL string to query the data on your table
strsql = "SELECT * " & _
"FROM [Yourtablename] " & _
"WHERE ((([YourTableName].[FirstName]) ='" & me.FormFirstNameField & "' AND ([YourTableName].[LastName]) ='" & me.FormLastNameField & "' AND ([YourTableName].[DOB]) =#" & me.FormDOBField & "#));"
set rst = db.openrecordset(strsql) 'This opens the recordset
if rst.recordcount <> 0 then
'Enter code to inform user information already exists
else
'Enter code if information does not exits
end if
rst.close 'Closes the recordset
set rst = nothing 'Frees memory
set db = nothing 'Frees Memory
End Sub
Let me know if this code works or if I need to make changes based on your scenario.

Access SQL to save value in unbound textbox cannot save more than 255 characters

I've read through a couple similar posts, but not found a solution for this issue:
I have a form with an unbound rich text, multiline textbox named tbxNote. When the textbox is exited, I use VBA code to create an SQL string which I subsequently execute to UPDATE a table field [Note] with the value in the unbound textbox. [Note] is a "Long Text" field (from my understanding, "Long Text" is equivalent to what used to be called a "Memo" field). The backend is an Access database.
Problem is: Only the first 250 characters of what is in tbxNote get stored in the target table field [Note] even though other "Long Text" fields in other tables are accepting values much longer than 250 characters. So, it does not seem to be an issue with the field type or characteristics in the backend table.
Furthermore, if I manually open the target table and paste 350 characters into the same [Note] field in the target table, all 350 characters get stored. But, if I load up that record into the form or put the same 350 characters into the form's tbxNote textbox, only 250 characters are pulled into tbxNote or saved out to [Note].
Is there a way to store more than 250 characters in an unbound textbox using an UPDATE SQL in code?
In case it matters, here's the SQL code that I used to prove only 250 of 350 characters gets saved to the table field [Note]:
dbs.Execute "UPDATE tblSupeGenNotes " & _
"SET [NoteDate] = #" & Me.tbxNoteDate & "#, " & _
"[SupeType] = " & Chr(34) & Me.cbxSupeType & Chr(34) & ", " & _
"[SupeAlerts] = " & alrt & ", " & _
"[Note] = " & Chr(34) & String(350, "a") & Chr(34) & " " & _
"WHERE [SupeGenNoteID] = " & Me.tbxSupeGenNoteID & ";"
Of course, normally I'd have Me.tbxNote instead of String(350, "a") but the String proves that only 250 of the 350 characters get stored in the [Note] field.
I must be missing something simple, but I cannot figure it out.
Unfortunately, you posted test code works, but you FAILED to post your actual update string that fails. A common (and known) problem is if you include a function (especially aggregates) in your SQL, then you are limited to 255 characters.
In fact this can apply if you have function(s) that surrounds the unbound text box and is used in the query.
So such an update should and can work, but introduction functions into this mix can cause problems with the query processor.
If you included the actual update, then the above issue(s) likely could have been determined.
So the workarounds are:
Don’t use any “functions” directly in the SQL update string, but build up the string.
So in place of say:
Dbs.Execute "update tblTest set Notes = string(350,’a’)"
Note how above the string function is INSIDE the sql.
You can thus place the function(s) OUTSIDE of the query and thus pre-build the string - the query processor is NOT executing nor will it even see such functions.
So we can change above to as PER YOUR EXAMPLE:
Eg:
Dbs.Execute "update tblTest set Notes = ‘" & string(350,’a’) & "’"
(this is how/why your posted example works, but likely why your actual code fails). So functions can (and should) be moved out of the actual query string.
Also make sure there is NO FORMAT in the formatting for the text box, as once again this will truncate the text box to 255.
And as noted here the other suggestion is to consider using a recordset update in place of the SQL update.
Using a recordset can often remove issues of delimiters and functions then become a non issue.
So such SQL updates can work beyond 255 characters, but functions need to be evaluated in your VBA code before the query processor gets its hands on the data as per above examples.
And as noted remove any “format” you have for the text box (property sheet, format tab).
#HansUp's suggested trying a DAO recordset to update the table. That did the trick! Thank you, HansUp. HansUp requested that I post the answer, so, here is the code that worked for anyone else who comes across this thread:
Dim dbs As DAO.Database
Dim rsTable As DAO.Recordset
Dim rsQuery As DAO.Recordset
Set dbs = CurrentDb
'Open a table-type Recordset
Set rsTable = dbs.OpenRecordset("tblSupeGenNotes", dbOpenDynaset)
'Open a dynaset-type Recordset using a saved query
Set rsQuery = dbs.OpenRecordset("qrySupeGenNotes", dbOpenDynaset)
'update the values vased on the contents of the form controls
rsQuery.Edit
rsQuery![NoteDate] = Me.tbxNoteDate
rsQuery![SupeType] = Me.cbxSupeType
rsQuery![SupeAlerts] = alrt
rsQuery![Note] = Me.tbxNote
rsQuery.Update
'clean up
rsQuery.Close
rsTable.Close
Set rsQuery = Nothing
Set rsTable = Nothing
AH! Another bit to the solution is that prior to using the DAO recordset, I was pulling values from the table into a listbox and from the listbox into the form controls (instead of directly into the form controls from the table). Part of the problem (I believe) was that I was then populating the form controls from the selected item in the listbox instead of directly from the table. I believe listboxes will only allow 255 characters (250 characters?) in any single column, so, everytime I pulled the value into the textbox from the listbox, the code was pulling only the first 255 characters into the textbox. Then, when the textbox was exited, the code was updating the table with the full textbox text, but when it was pulled back into the form through the listbox, we'd be back down to 255 characters. Of course, when I switched to the DAO approach, I also switched to reading the textbox value directly from the table instead of pulling it from the listbox.
Moral: Beware of pulling Long Text values through a listbox!
Thanks to everyone who helped me solve this. Sorry for such a newbie error seeming more complicated than it was.
I assume you are using the SqlClient library. In which case, I recommend trying SqlParameters rather than creating a SQL string the way you are. With the SqlParameter you can specify the size of each parameter. http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.parameters(v=vs.110).aspx?cs-save-lang=1&cs-lang=vb#code-snippet-2 . I am a C# dev so my apologies about doing the example code below in C#:
string param = "Hello World";
byte [] encodedStr = Encoding.UTF8.GetBytes(param);
SqlParameter sqlParam = new SqlParameter();
sqlParam.Size = encodedStr.Count; // uses byte count
you could condense it by calling Encoding.UTF8.GetBytes(param).Count. Anyways, this might fix your issue

How to run a SQL select statement in VB

I have been looking around but can't seem to find out how to do this.
I'm trying to execute a SELECT sql statement in VB that takes in a parameter from a form. For example the user selects a From and a To date and the SQL should take what they selected.
I know that you cannot use the DoCmd.Execute method for SELECT SQL so I would need to open the record set - but how? This is what I have tried so far
Dim recordSet As DAO.recordSet
Dim SQL As String
SQL = "SELECT * FROM tblWebMeetingData"
Set recordSet = CurrentDb.OpenRecordset(SQL)
'More code in here
recordSet.Close
Set recordSet = Nothing
Because this executes without an error I assume it's actually getting the results - so is there a way to see what it is actually returning?
Thanks
First: It's a good advice to rename the recordset to rs, for example, because "recordset" is a reserved name. This is misunderstandable.
This recordset contains the records you queried by your SQL statement. You may access those data by rs.fields("fieldname").value. Move to the next recordset with rs.movenext.
To incorporate the form's control value I use the way to build the full SQL statement prior to opening the recordset. Say the form is named "myform" and the control "mycontrol", you may write some kind of
SQL = "SELECT * FROM tblWebMeetingData WHERE myfield = " & forms!myform.mycontrol.value
Please be sure the form only contains valid values, because any wrong formatted value will directly lead to an SQL execution error.
I hope it was this, what you wanted.
Here you have come sample code about iterating trought RecordSet and using values from it( I hope it helps a bit):
Dim i As Integer
Do While Not rs.EOF
Sheets("D_" & day).Cells(i, 1) = rs.Fields(0).Value
Sheets("D_" & day).Cells(i, 2) = rs.Fields(1).Value
rs.MoveNext
i = i + 1
Loop
rs.Close

What is the MS Access SQL syntax to create a field of type Hyperlink?

I'm working on a C# project that uses System.Data.OleDb.OleDbCommand class to create and alter tables in an MS Access DB. I generate the SQL statement, pass it to the object, then call the ExecuteNonQuery function. I was able to figure out the proper MS Access SQL syntax to create columns of the following Access data types:
AutoNumber: ALTER TABLE table-name ADD COLUMN column-name COUNTER|AUTOINCREMENT
Currency: ALTER TABLE table-name ADD COLUMN column-name MONEY
Date/Time: ALTER TABLE table-name ADD COLUMN column-name DATE
Memo: ALTER TABLE table-name ADD COLUMN column-name MEMO|TEXT
Number: ALTER TABLE table-name ADD COLUMN column-name NUMBER
OLE Object: ALTER TABLE table-name ADD COLUMN column-name OLEOBJECT
Text: ALTER TABLE table-name ADD COLUMN column-name CHARACTER
Yes/No: ALTER TABLE table-name ADD COLUMN column-name BIT
The only type I haven't figured out how to create is Hyperlink. Does anyone know the syntax for that one?
This is a case where you can't use DDL but must use DAO. What you're looking for is the .Attributes property of the DAO Field type. In VBA, this code does the trick (you'll have to figure out how to do this with DAO in C#):
Dim tdf As DAO.TableDef
Dim fld As DAO.Field
Set tdf = CurrentDB.TableDefs("MyTable")
Set fld = tdf.CreateField("Hyperlink", dbMemo) ' dbMemo = 12
fld.Attributes = dbHyperlinkField ' 32768
tdf.Fields.Append fld
Set fld = Nothing
Set tdf = Nothing
If you check the data type of this field in Access:
CurrentDB.TableDefs("MyTable").Fields("Hyperlink").Type
it returns 12, which is equal to the VBA global constant dbMemo (that's how I figured out how to do it, i.e., created a Hyperlink field in the Access UI, then checked its datatype). The value for dbHyperlinkField is 32768, but cannot be assigned directly as a data type -- it is instead a sub-attribute of a memo field.
This is a case of Access extending Jet by using a custom attribute for it to work with the data differently than the limited number of Jet data types. It's also clear that the Hyperlink field type is only relevant if you're using the data from Access itself. If you're using some other application to work with the data, you're gaining nothing at all from using a hyperlink data field.
Also, I'm with those who recommend not using a field of type Hyperlink because I've tried it and it's just a pain in the ass. Also, given that it's really a memo field, it's subject to all the problems that come with memo fields. That is, the data is not actually stored with the data table -- all that's stored in the main record is a pointer to the data page where the real data is stored, and those pointers are one of the frailer parts of Jet. Memos are worth that risk, because when you need to store more than 255 characters, you need to do it. I can't see that there's any significant functionality added by the Access-specific Hyperlink field type that it's worth the trouble in working with it in code or the risk that comes from the fact that it's implemented behind the scenes as a memo field.
I had a play around with this with ADOX in C# and the only way I found to do it was set the "Jet OLEDB:Hyperlink" property after creating the column in the table but before actually adding the table to the Tables collection.
The following example requires a COM reference to Microsoft ADO Ext. 2.8 for DDL and Security:
ADOX.Catalog cat = new CatalogClass();
cat.let_ActiveConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;" +
"Data Source=C:\\Tempo\\Test_Access2007.accdb");
ADOX.Table tbl = new ADOX.TableClass();
tbl.Name = "TestHyperlink";
tbl.Columns.Append("my_hyperlink", ADOX.DataTypeEnum.adLongVarWChar, 0);
ADOX.Column col = tbl.Columns["my_hyperlink"];
col.ParentCatalog = cat;
col.Properties["Jet OLEDB:Hyperlink"].Value = true;
cat.Tables.Append(tbl);
Although Microsoft complicates matters by having a hyperlink field in a database as an object with properties, setting it seems reasonably straightforward, using this kind of syntax :-
UPDATE myTable
SET HyperlinkField = "(text to display)#(Target URL)#(hyperlink subfield, if required)"
WHERE clause
Actually, I'm using this to create a form over a table, where the link points to a file rather than a web address (it's a list of drawings so the user can click the link to open the drawing). In this case, the URL is the RELATIVE path to the file, e.g. "..\documents\myFile1.dat".
I'm aware I could use other methods to implement the same, but the users understand hyperlinks.
I've not tested how these links behave when the source database is moved, incidentally.
You would use two CHARACTER fields to represent the content of a hyperlink, one that contains the URL to the resource you want the hyperlink to link to (stored as plain text), and another that would hold the text that's shown in the browser (that is, if the text shown in the browser is different from the URL itself).
When displaying the link in a webpage in C#, you can create a hyperlink:
Hyperlink hyp1 = new Hyperlink
hyp1.Text = datarow.DisplayText
hyp1.NavigateURL = datarow.TargetURL
Following raven instructions, dummy programmers (like me) can use this sub to add, by access VBA code, an hyperlink field.
Sub AddLinkField(Table, FieldName)
Dim dbs As DAO.Database
Set dbs = CurrentDb()
Dim tdf As DAO.TableDef
Dim fld As DAO.Field
Set tdf = dbs.TableDefs(Table)
Set fld = tdf.CreateField(FieldName, dbMemo) ' dbMemo = 12
fld.Attributes = dbHyperlinkField ' 32768
tdf.Fields.Append fld
Set fld = Nothing
Set tdf = Nothing
End Sub
The relevant SQL to insert a new record with a link to (e.g) c:\ is..
SQL = "INSERT INTO Table VALUES (...,'LinkVisualizedText #c:\#')"
to execute it is...
CurrentDB.Execute SQL
There is no real concept in sql of a datatype of hyperlink. You would store the url as you would any text and then when you're using it in your application you would create the hyperlink on that end.