Creating Multiple Links in an Access Textbox - vba

I have a form in Access 2016 with a textbox in which I need to have multiple, semi-colon delimited hyperlinks (which will be dynamically created). What I've decided to do is create a "hyperlink construction string" in VBA, then assign them to the value of the textbox. So, something like:
Me.Field.Value = {link: www.google.com : "Google"} & "; " & {link: www.yahoo.com : "Yahoo"}
...would result in this being in the text box:
Google; Yahoo
My problem is, I can't seem to figure out the syntax to create an individual link in the textbox without making the entire textbox a single hyperlink, which isn't gonna work.
I was working with a few solutions that I've found. I read that this would create the link in the way I need, but it just comes through as literal text with the pound signs:
"Google # www.google.com # Some Argument"
I also tried setting the textbox to rich text, then setting the value to include rich text code for a hyperlink... but that's not working:
"{\field{\*\fldinst HYPERLINK ""http://www.google.com/""}{\fldrslt http://www.google.com}}"
I also thought about designing a Query that will return the hyperlinks. But, I kind of wanted to make it a VBA thing, because I'll have more flexibility in how I create the value. Does anyone have any ideas?
Note: I understand that multiple values should be in a 1:M relational database. They are. But, the requirements of the task are to get all the M values for a 1 entity, then list them out in semi-colon, delimited fashion, which all serve as links to a Details table for the M entity.

Regular textboxes (text only) don't support this.
It is possible with Rich text textboxes. In contrast to the name, they actually use a subset of HTML, not RTF.
With ideas from here I got this working:
Private Sub cmdInsertHyperlinks_Click()
Dim url1 As String, url2 As String
url1 = "D:\tmp\test.jpg"
url2 = "D:\tmp\test space.txt"
Me.rText.Value = "<div>" & _
"file://" & url1 & "" & _
" other text between hyperlinks " & _
"file://" & url2 & "" & _
"</div>"
End Sub
Note: the linked thread says you must URL-encode the links (space to %20 etc), but at least for my simple test, that wasn't necessary.
Note 2: You can't have a different display text and link url, at least I didn't get that to work.

Related

How to update an add-in field code without losing field data (MS Word)?

I have an add-in field in MS Word which also has some hidden data. I want to update the field's code text. However, when I do so and read my hidden data again, they are gone. See this minimal example:
Sub testUpdatingFieldCode()
Dim newField As Field
Set newField = ActiveDocument.Fields.Add(Range:=Selection.Range, Type:=wdFieldAddin)
newField.Code.Text = " ADDIN mycode \* MERGEFORMAT "
newField.Data = "mydata"
Debug.Print "Code: " & newField.Code.Text
Debug.Print "Data: " & newField.Data ' works - prints "Data: mydata"
newField.Code.Text = " ADDIN mycodechanged \* MERGEFORMAT "
Debug.Print "Code: " & newField.Code.Text
Debug.Print "Data: " & newField.Data ' doesn't work - prints "Data: "
End Sub
Is this normal behaviour or a bug? Is there a suggested way to update field codes without losing the data?
I could save the Data to a variable like this but I'm worried about performance (I ultimately need to do this for tens or hundreds fields at a time):
Dim previousData As String: previousData = newField.Data
newField.Code.Text = " ADDIN my_code_changed \* MERGEFORMAT "
newField.Data = previousData
Trying your code, it does insert the field and does change the value.
The problem seems to be with .Data because the field is there in the document.
I join John Korchok's suggestion that you use Document variables instead. They can hold text information and it is not normally accessible to the user. It is not in the text of the document and so not subject to accidental deletion by the user. You can have multiple variables in a document. They can be displayed in the document if you want through a DocVariable field which is a reporting, not an editing, field.
Here is a link to the support document on document variables. Two code examples from that page:
ActiveDocument.Variables.Add Name:="Value1", Value:="1"
MsgBox ActiveDocument.Variables("Value1") + 3
For Each myVar In ActiveDocument.Variables
MsgBox "Name =" & myVar.Name & vbCr & "Value = " & myVar.Value
Next myVar
As you can see, this is a much simpler construction than using the AddIn Field. There are several utilities available that give access to document variables from within the User Interface but nothing in Word out of the box that allows the user to change variables without vba.
[EDIT to address concerns in first comment.]
You can use the Feedback mechanism in Word to complain about the problem with the Addin field. I do not know that it will be fixed because there are such better tools available. More likely is that they will delete or deprecate the field. I know of no way to work around this and get the result you want. Even deleting the field and recreating it does not allow you to get the data.
You can use Document Properties as well as Document Variables. Those are available to the user through the Advanced Properties. In addition, certain properties are available through the Quick Parts menu where a change in the property content control in the document changes the property itself. These are mapped to XML nodes. Like Document Variables, all Document Properties can be displayed through a (reporting) field: DocProperty. My page on Repeating Data shows some uses that can be made using these built-in mapped Document Property Content Controls.

How can I use special chars in VBA of Microsoft Word?

I've created a set of macro files in Microsoft Word's VBA as a sort of a CAT tool (CAT = https://en.wikipedia.org/wiki/Computer-assisted_translation). The problem is that there are cases where I display the text needed to be translated and the user needs to input text in his own language. That might include some special chars, like "ăîâșț/ĂÎÂȘȚ", or even quotes or brackets. Is there any way to use those in some InputBox function? Or, at least, some way to let the user input the text he needs in some TextBox or something?... Or how should I approach this?... Maybe UTF-8 support would be what I need? Or?... Any help would be appreciated!...
I've tried Microsoft Word's vba function InputBox. I'm also thinking if, maybe, I would be able to create my own InputBox, with my conditions on it, I might be able to have one that accepts those chars too, or all the chars into some string variable... Here is something someone on StackOverflow says:
Is it possible to create an 'input box' in VBA that can take a text selection with multiple lines as an input? (I'm referring to gizlmo's answer...)
Here are 3 lines of code that contain that (although it's more of a how to question, not a debugging question, so those are not really needed...)
MsgBox ("Ziua " & Str(ziua) & " - " & titlurien(ziua))
titluales = InputBox("Titlul original: " & titlurien(ziua), "Ziua: " & Str(ziua) & ", Rapsodia Realitatilor " & monthname(lunanecesara) & Str(annecesar))
titluriro(ziua) = titluales
I expect the output to be exactly what he typed, whether it's quotes, brackets or special characters (like "ăîâșț"/"ĂÎÂȘȚ")...
A VBA InputBox will take any character typed or pasted into it. The characters available to type depends on the Language version of Windows and Office that the end user has installed.
Below is a test I just made with your example character string "ăîâșț/ĂÎÂȘȚ"
SpecialCharInput()
Dim str As String
str = InputBox("Enter you text", "Special Test Input Box")
Debug.Print str
End Sub
On my English language system, the only trouble it had was with the upper and lower case "ȘȚ" Turkish characters. By trouble I mean it turned those characters into question marks "??" in the result string. I'm sure though, if my system supported the Turkish language that those characters would be recognized and outputted properly.

Pass Quotes from a text box to external URL

I have a simple VB.net app that has a text box that I pass to a URL for searching. So let's say I want to send this:
search "*ball"
So, my search will look for everything with ball after the *. The problem is, it strips the quotes when I send it.
System.Diagnostics.Process.Start("https://searchgames.local/search?game=" & TextBox1.Text)
How can I look for Quotes in my text box, then if they are there, pass them appropriately to the URL I am sending to. Below my code just makes sure they actually enter something into the textbox. As always, help is always appreciated.
If TextBox1.Text = "" Then ' If user does not enter any text
MsgBox("Enter text to search on." & vbCrLf & Err.Description, MsgBoxStyle.Information, "Need search term to search on.")
TextBox1.Focus() 'Set the cursor back to the text box
If you are in a web app, you can use HttpUtility.UrlEncode to properly escape the quotation mark characters. Outside of a web application, MSDN recommends that you use WebUtility.UrlEncode. You could also use Uri.EscapeDataString, but there seem to be some problems with it.
So, for instance, you could do this:
Process.Start("https://searchgames.local/search?game=" & HttpUtility.UrlEncode(TextBox1.Text))
Or this:
Process.Start("https://searchgames.local/search?game=" & WebUtility.UrlEncode(TextBox1.Text))
Or this:
Process.Start("https://searchgames.local/search?game=" & Uri.EscapeDataString(TextBox1.Text))
Try this:
Dim url as string = "https://searchgames.local/search?game=" & TextBox1.Text
Dim encodedurl as string = HttpContext.Current.Server.UrlEncode(url)
System.Diagnostics.Process.Start(encodedurl)

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

Escape Characters in a resource file string?

I've been globalizing an application and have been using Resx Manager to make my life easier. I ran into a multi-line string literal and it stumped me.
How would I handle the escape characters when making this string into a resource?
If Not RelayMessage(
"Are you sure you want to do the selected action?" & vbCrLf &
"A confirmation message will be sent to the user." & vbCrLf &
"Please ensure you want to perform this action before hitting accept.",
My.Resources.Confirmation, RelayMessageOptions.Confirm_YesNo) =
DialogResult.Yes
How would I make that string into a resource?
In the standard VS resource manager (is this the manager you're using?) you can enter a multi-line string resource directly in the editor by using shift-Enter:
Note that this is actually stored as a string with CR+LF pairs, assisted by the space="preserve" attribute. Viewing the .resx file in a text editor:
Results using a standard message box:
MessageBox.Show(strings.myString)
I don't know how it is usually handled in globalization problems. But an easy way would be to define your own escape character formats. For example you could define \n as a newline character. When you actually use your ressource you could then use
If Not RelayMessage(Strings.Replace(myResourceString, "\n", vbCrLf),
My.Resources.Confirmation, RelayMessageOptions.Confirm_YesNo) =
DialogResult.Yes
instead of
If Not RelayMessage(myResourceString,
My.Resources.Confirmation, RelayMessageOptions.Confirm_YesNo) =
DialogResult.Yes
Or you could manually add chars with character codes 10 and 13 (e.g. ChrW(10) & ChrW(13)) at the vbCrLf location in your ressource string. This equals a vbCrLf (meaning a carriage return (10) + line feed (13)). This would avoid manipulation of the source code. Other stuff like Tab (9) have codes, too. These are called control characters. Take a look at the wikipedia http://en.wikipedia.org/wiki/Control_character