My users have a number of backend .accdb databases (which I can't access directly). I need to code some vba to modify the structure of some of the tables in these databases to convert Text Fields to Rich Text memos. (The fields already contain text including Access "rich-text" i.e. the relevant html coding).
I need to:
Modify the field to be a rich text memo.
Modify the existing contents (if applicable) to display correctly as Access rich text in forms, datasheets and reports.
I can write a SQl statement that will modify a field from TEXT (255) to MEMO:
ALTER TABLE tblSource ALTER COLUMN Detail1 MEMO
However, this leaves the resultant memo field as a plain text memo.
I have considered creating a new Rich Text Field and then copying the contents of the old one (using a SQL CREATE TABLE statement followed by an UPDATE statement that applies the Plaintext function to the contents of the old field and then copies the result to the new field, and then further SQl to delete the old field and rename the new) but can't find out how to create a rich-text memo (default seems to be plain text).
Extensive web searches haven't shown up any additional techniques I can deploy. This is a process that will be run once for each file, so it doesn't need to be elegant or quick but it does need to be bomb-proof!
Since Rich Text is not a datatype and is not a field property which can be defined or modified with a SQL statement, you will need VBA to set the field's TextFormat property.
You can adapt techniques from this code sample.
Dim db As DAO.Database
Dim tdf As DAO.TableDef
Dim fld As DAO.Field
Set db = CurrentDb
Set tdf = db.TableDefs("Table1")
Set fld = tdf.Fields("memo_fld")
Debug.Print "acTextFormatPlain: " & acTextFormatPlain & _
"; acTextFormatHTMLRichText: " & acTextFormatHTMLRichText
With fld.Properties("TextFormat")
Debug.Print "TextFormat: " & .Value
If .Value = acTextFormatPlain Then
.Value = acTextFormatHTMLRichText
Debug.Print "TextFormat changed to: " & .Value
End If
End With
Note that code is run from the database which contains the target table. If Table1 was actually a link to a table in another Access db file, the code would fail.
Note also that only applies to a memo field. The TextFormat property is not created for regular text datatype fields, so this will throw error #3270, "Property not found."
Debug.Print tdf.Fields("some_text").Properties("TextFormat").Value
Since you will be converting regular text fields to memo fields, that point is probably not a concern. I mentioned it only in case you stumble into it.
ColeValleyGirl discovered the TextFormat property is not always created for a new memo field.
Related
I've got a memo field in MS Access 2010 and I'm trying to paste a large piece of text in it (about 160k chars).
When I paste directly in the table I get an error that "the text is too long to be edited".
The same thing happens when trying to do it via a form.
I've also tried to save the text to a file and the to read the file contents with VBA and then update the table by running a UPDATE table sql statement. In this case I get a runtime error 3035 that "System resource exceeded".
According to this postI should be able to store 1GB of data
How can I update a memo field with my text otherwise?
You can use recordsets to update the field. That way, you won't exceed the maximum length of an update query
(incomplete code, need more details to write more exact code)
Dim str As String
'Read text file into str
Dim rs As DAO.RecordSet
Set rs = CurrentDb.OpenRecordset("MyTable")
rs.AddNew
rs.Fields("MyMemoField").Value = str
rs.Update
rs.Close
I'm using Access 2010 and I'm rusty as heck... So I create a main form and an unbound subform. Unbound to the main form, I should say, but bound to a record source. Things work fine.
In the subform, I have a dropdown called cboGIReqNbr with IDs in it. I also have a textbox called txtGIReqNbr. What's supposed to happen is that when you choose a cboGIReqNbr from the dropdown, txtGIReqNbr is supposed to populate with the description.
I've got this in the AfterUpdate event of cboGIReqNbr:
Dim db As Database
Dim rec As Recordset
Dim sSql As String
Set db = CurrentDb
sSql = "Select GI_Request_Name from tblGIRequest where GI_Request_Nbr = '" & Me.cboGIReqNbr.Text & "'"
Set rec = db.OpenRecordset(sSql)
Me!txtGIReqNbr.SetFocus
Me!txtGIReqNbr.Text = rec(0) <-- PROBLEM
Me.txtLanID = Forms!frmHoursAssigned.cboEmployee.Value
rec(0) does, in fact, populate with the correct text.
The error I get on the problem line is; "This property is read-only and can't be set". None of my objects should be read-only, and all the examples I could find online pointed to people using reserved words (i.e. using "Name" as a field name).
Anyone know how to solve this?
You should use the .Value property to assign values to a text box. .Text changes the visible value and can only be used when the field has focus. .Value stores the actual value and can be used at any time.
Me!txtGIReqNbr.Value = rec(0)
Also see: Distinction between using .text and .value in VBA Access
I have a basic table in access with several populated fields. I would like to explore if there is a way, preferably through the GUI (or maybe through SQL), to add a field containing the name of the table itself. I see only the following data formats for fields: Short text, Long text, number, Date/time, Currency, Autonumber, Yes/No, OLE Object, Hyperlink, Attachment and Calculated. There is nothing pertaining to data object parameters themselves such as table, field or query names or parameters...
You can access the meta data of the database via VBA (Visual Basic for Applications) macros.
For example, this can show all table names:
Option Compare Database
Public Sub Test()
Dim database As DAO.database
Dim tableDef As DAO.tableDef
Set database = CurrentDb
For Each tableDef In database.TableDefs
MsgBox tableDef.Name
Next
End Sub
Is there a way to prevent MSAccess from concatenating 'dbo_' as the prefix to tables linked from a SQL Server db?
No. Microsoft Access' native naming convention process will force the name <schema>_<ObjectName> as your default table name. There are no controls or settings which will allow you to change that, except in code. It's rather complex and goes beyond the scope of this question, but if you do the linking in code (which I do) then you can store the TableAlias and create the linked table name that way.
You can write your table definition in the code to attach the table as below where
strTableAlias is your display name in Access
strTableName is your table name with schema <schema>.<ObjectName>.
Dim td As DAO.TableDef
set td = CurrentDb.CreateTableDef(strTableAlias, dbAttachSavePassword, _
strTableName, strConnectionStr)
CurrentDb.TableDefs.Append td
If you don't do the linking in code as mentioned by Johnny you can rename the links with this VBA code:
Public Sub Remove_DBO_Prefix()
Dim obj As AccessObject
Dim dbs As Object
Set dbs = Application.CurrentData
'Search for open AccessObject objects in AllTables collection.
For Each obj In dbs.AllTables
'If found, remove prefix
If Left(obj.Name, 4) = "dbo_" Then
DoCmd.Rename Mid(obj.Name, 5), acTable, obj.Name
End If
Next obj
End Sub
Courtesy https://www.microsoftaccessexpert.com/Microsoft-Access-Code-RemoveDBOPrefix.aspx
If you're doing this with the idea of using queries that you generate in Access outside of Access remember that Access creates it's own sql dialect so you may need to convert double quotes to single and # to ' among other things.
I am not sure as to the best way to describe this problem to make it clear to you. I have recently changed a field on a form which previously was a standard field but for the sake of user friendliness and data quality control, has now become a drop down field linked to a table and therefore provides a drop down list when the user is to enter data (instead of typing).
The issue encounterd is as follows:
This field, upon entering a value (in this case the name of a team (below listed as txtTeam) triggers an after update event so that using ADO code takes the team name, references it to an underlying team table and then copies corresponding values into the fields: "txtCity", "txtCountry", "txtCAP", "txtOfficialTeamName", ect (see below)
Unfortunately, once i changed the team field to a list field linked to the table, the If statement which I flagged below with (* HERE IS MY PROBLEM - ...) is no longer valid and unfortunately the ADO copy/paste code no longer works.
**Note: When going into the VBA editor and hovering my mouse over "Team_name" and "txtTEam" the following result appears showing me that the issue is directly linked to the fact that I have converted this field to a drop down field.
Team_name = Operational Excellence (the actual name of the team selected)
txtTEam = '71' (the ID number of the team "Operational Excellence" on the underlying table
I hope someone can help me with this because this form is really useful for me an without this code, it loses alot.
Thanks,
A
Dim rstTEAM As New ADODB.Recordset
rstTEAM.Open "tblTeams", CurrentProject.Connection, _
adOpenForwardOnly
Do Until rstTEAM.EOF
If rstTEAM!Team_name = txtTEam Then (*** HERE IS MY PROBLEM- this statement is no longer TRUE)
txtCity = rstTEAM!City
txtCountry = rstTEAM!Country
txtCAP = rstTEAM!CAP
txtOfficialTeamName = rstTEAM!Official_Team_Name
txtStreet = rstTEAM!Street
txtDivision = rstTEAM!Division
txtNumerotel.SetFocus
blnAggiunto = True
Exit Sub
Else
rstTEAM.MoveNext
End If
Loop
rstTEAM.Close
Set rstTEAM = Nothing
Now that you are using a listbox, you need to reference the control properly. I assume you are not allowing multi-select, so you should reference as follows (assuming the key is Col 0, else use 1 or 2...:
If rstTEAM!Team_name = Me.txtTEam.Column(0) Then
If allowing multi-select, you would use something like:
Dim varItem As Variant
For Each varItem In Me.txtTEam.ItemsSelected
strSQL = strSQL & Me.txtTEam.Column(0, varItem)
Next varItem