Allow edits from different users appear in different color inside memo box : Microsoft Access 2010 - database

I have a memo field which contains rich text. I am able to identify a user and change all the text in the box instead of just the text they added.
I am looking to write code which allows the text to be edited and after update , the edited text will appear a different color than the original text in the memo field.
I have tried :
Dim strNew As String
Dim strOld As String
If Me.txt_username_id = "grant" Then
strOld = Me.Form!txtnotesaboutproduct1.OldValue.ForeColor = vbBlack<br/>
strNew = Me.Form!txtnotesaboutproduct1.ForeColor = vbRed
End If
I have also tried
Dim ctlOld As TextBox<br/>
Set ctlOld = Me.Form!txtnotesaboutproduct1
If Me.txt_username_id = "grant" Then
ctlOld = Me.Form!txtnotesaboutproduct1.OldValue.ForeColor = vbRed
End If

Generally, I do this with a continuous subform for Notes, so that I can hold the data, date and user, rather than just one formatted text box. Though I do realize this might be a lot more real estate that you might have, you can use a conditional format within the subform. I do agree that if it is possible, you'll likely need to use HTML and not .Forecolor, which will change the entire box.

Related

Outlook VBA - .RTFBody Formatting from Byte Array

I am developing a VBA / VSTO script that interacts with Outlook.
I have a process that should, essentially, do this:
Read in an .oft file that is in Rich Text Format
Parse the RTFBody array into a String
Replace some elements of the String (so a line that says "%SUBJECT%" will instead be "IMPORTANT MEETING")
Convert that String back into the RTF array format (this uses a Rich Text Box)
Replace the RTFBody with the updated RTF array
Display the finished email
This is all done. Except the finished email is just RTF garbage with no formatting.
So what is meant to be a lovely table is instead this:
{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff37\deff0\stshfdbch0\stshfloch37\stshfhich37\stshfbi37\deflang2057\deflangfe2057\themelang2057\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f34\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria Math;}{\f37\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304
(You can imagine the rest.)
The code is:
Dim objMsg As AppointmentItem
' 1. Read in an .oft file that is in Rich Text Format
objMsg = Application.CreateItemFromTemplate(currentLocation & "\template.oft")
' 2. Parse the RTFBody array into a String
Dim rtfArray = objMsg.RTFBody
Dim Encoding = New System.Text.ASCIIEncoding()
Dim rtfBody = Encoding.GetString(rtfArray)
' 3. Replace some elements of the String (so a line that says "%SUBJECT%" will instead be "IMPORTANT MEETING")
rtfBody = Replace(rtfBody, "%SUBJECT%", "Important Meeting")
' 4. Convert that String back into the RTF array format (this uses a Rich Text Box)
Dim rtb = New System.Windows.Forms.RichTextBox()
rtb.Text = rtfBody
Dim newArray = System.Text.Encoding.ASCII.GetBytes(rtb.Rtf)
'5. Replace the RTFBody with the updated RTF array
objMsg.RTFBody = newArray
'6. Display the finished email
objMsg.Display()
Does anyone have any awareness of what the solution to this problem is?
And before anyone suggests HTML... I would love to! But this is an AppointmentItem so it doesn't support HTMLBody.
To parse the RTFBody array into a string you have dealt with ASCII encoded string:
Dim rtfArray = objMsg.RTFBody
Dim Encoding = New System.Text.ASCIIEncoding()
Dim rtfBody = Encoding.GetString(rtfArray)
But to set the RTFBody you deal with UTF8 for an unknown reason:
Dim newArray = System.Text.Encoding.UTF8.GetBytes(rtb.Rtf)
Try to use the same encoding:
Dim newArray = System.Text.Encoding.ASCII.GetBytes(rtb.Rtf)
Be aware, The Outlook object model supports three main ways of customizing the message body:
The Body property returns or sets a string representing the clear-text body of the Outlook item.
The HTMLBody property of the MailItem class returns or sets a string representing the HTML body of the specified item. Setting the HTMLBody property will always update the Body property immediately. For example:
Sub CreateHTMLMail()
'Creates a new e-mail item and modifies its properties.
Dim objMail As Outlook.MailItem
'Create e-mail item
Set objMail = Application.CreateItem(olMailItem)
With objMail
'Set body format to HTML
.BodyFormat = olFormatHTML
.HTMLBody = "<HTML><BODY>Enter the message text here. </BODY></HTML>"
.Display
End With
End Sub
The Word object model can be used for dealing with message bodies. See Chapter 17: Working with Item Bodies for more information.
Note, the MailItem.BodyFormat property allows you to programmatically change the editor that is used for the body of an item.

Loop textboxes and cells

I need some help making this code shorter. I have a lot of textboxes with times in my form which I want to copy to my Excel file. Some of the boxes needed to be 15min less in Excel sheet and I want to loop through these textboxes and and copy the result into the correct cell. My code works but I want to make it for more textboxes at once.
Dim d1re1 As Date = TextBox5.Text
TextBox5.Text = d1re1.ToLongTimeString()
Dim d1nre1 As Date = d1re1.AddMinutes(-15)
xlsp1.Cells(7, 100) = d1nre1.ToLongTimeString
Dim d1re2 As Date = TextBox7.Text
TextBox7.Text = d1re2.ToLongTimeString()
Dim d1nre2 As Date = d1re2.AddMinutes(-15)
xlsp1.Cells(7, 102) = d1nre2.ToLongTimeString
The idea here that the lines somehow doing the same but with different parameters.
Here functions come in the picture. You can just create generic method call it for ex : SetDateToFieldscand takes the parameters : the source textbox and which cell it needs to update.
Like this you just need only to call the method with different params.

LineBreak within an excel cell using GemBox Spreadsheet

Is it possible to add a line break within an excel cell using the GemBox Spreadsheet API? For example if you're in Excel you can press Alt+Enter and go to a new line in a cell. I'm having trouble finding a property on the CellStyle class in GemBox that allows this. Is it possible?
Thanks
Yes, it is possible, for example try the following:
var ef = new ExcelFile();
var ws = ef.Worksheets.Add("Sheet1");
ws.Cells["A1"].Value = "Sample";
ws.Cells["A1"].Value += "\n" + "Sample";
ef.Save("Sample.xlsx");
In short, just use the new line character in ExcelCell.Value.
Note that when you're assigning such a value, GemBox.Spreadsheet will automatically set ExcelCell.Style.WrapText property to true.

Multi-Session Variables in MS Access

Is there a way to store variables in access which retain their data even after access restarts? The idea is that I will log the date and time of when the form was last opened, which will allow me to only show records since it was last opened.
Since you are inside Access, just create a table to store such information!
In case anyone comes looking here for a method to store Permanent Variables (aka Multi-session Variables) without using Access tables. Here is the techique to achieve this.
Crux : Use TextBox DefautlValue to store data.
Dim strForm As String
Dim frm As Form
strForm = "FormName"
DoCmd.OpenForm strForm, acDesign, , , , acHidden
Set frm = Forms(strForm)
frm.Text0.Caption = "Test"
frm.Text0.DefaultValue = 4
Set frm = Nothing
DoCmd.Close acForm, strForm, acSaveYes
Important Note : Form needs to be open in Design view.

MS Access - open a form taking a field value from a previous form

I have a form in an MS Access database which lists all the landowners consulted with for a new electricity line. At the end of each row is a button which opens another form, showing the details of all consultation, offers made etc.
I am trying to use vb in MS Access to take the contactID and automatically put it in a field in the details form, so that landowner's consultation details will pop up automatically. I am not a vb programmer at all (I have a comp sci degree mostly in Java and I'm currently working as a GIS analyst but it's a small company so I've been asked to get an Access database working).
I want to say
[detailsForm]![contactID] = [landownerlist]![ID]
in a way that vb and access will be happy with. Then I can see if I'm on the right track and if it will actually work! What I have above does not actually work. It won't compile.
From Kaliana
If you wish to open a form to a new record and to set the ID there, you can use Openargs, an argument of Openform:
DoCmd.OpenForm "FormName",,,,acFormAdd,,Me.ID
The opened form would also need some code:
If Me.Openargs<>vbNullstring Then
Me.Id = Me.Openargs
End If
It is also possible to find:
Forms!LandownersList.Recordset.FindFirst "ID=" & Me.ID
or fill in a value:
Forms!LandownersList!Id = Me.ID
on the form being opened from the calling form.
You may want to look into the code that is behind these buttons. If you are using a docmd.openform you can set the 4th Setting to a where clause on openning the next form.
DoCmd.OpenForm "OpenFormName", acNormal, , "[contactID] = " _
& [detailsForm]![contactID] , acFormEdit, acWindowNormal
This assumes contact ID is numeric and doesn't require any quotes.
Using open args is the generally accepted solution, as alluded to by others. This just falls under the category of "For you edification":) One of the problems with using open args is that unless you are careful with your comments it's easy to forget what they were supposed to mean. Were you passing more than one? Which is which? How did I do it here? How did I do it there etc. For my own money, I standardized to this (below) so I can always pass more than one argument without fear, and when I review my code a year from now, I can still see what's what without a huge hassle:
Option Explicit
'Example use: DoCmd.OpenForm "Example", OpenArgs:="Some Filter|True"
Public Enum eForm1Args
eFilter = 0
eIsSpecial = 1
End Enum
Private m_strArgs() As String
Public Property Get Args(ByVal eForm1Args As eForm1Args) As String
Args = m_strArgs(eForm1Args)
End Property
Private Sub Form_Open(Cancel As Integer)
m_strArgs = Split(Nz(Me.OpenArgs, vbNullString), "|")
If LenB(Me.Args(eFilter)) Then Me.Filter = Me.Args(eFilter)
End Sub
Private Sub Command1_Click()
If LCase$(Me.Args(eIsSpecial)) = "true" Then
'Do something special
End If
End Sub
As previously posted OpenArgs is great for this. One trick I have learned is that it is easy to pass in multiple parameters if required as a delimited string (comma for example), the target form can then access these values using the Split() function thus:
StringArrayVariable()= Split(me.OpenArgs,",")
Me.textbox= StringArrayVariable(0)
Me.textbox1= StringArrayVariable(1)
etc.
This is air code so check out the helpfile for Split().
It is also possible to pass objects in OpenArgs as well, it requires some manual memory pointer manipulation and I don't have the code to hand but I'm sure a Google search will find some examples. This technique can cause some random crashes though. Be Warned!

Resources