Solved

Send an RTF as Read Only

Posted on 2008-10-10
12
903 Views
Last Modified: 2013-11-28
I have a report that I send via email in rtf format. Is there any way to make the file read only so that the recipient can't modify the document?
0
Comment
Question by:shanej
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 3
  • 2
  • +1
12 Comments
 
LVL 74

Expert Comment

by:Jeffrey Coachman
ID: 22692630
shanej,

No

In order to create a Read-Only Document, you can use the "SnapShot" format or save the Report as a PDF.

There are tons of free utilities to convert your report to PDF's.
here are two:
http://www.cutepdf.com/
http://www.lebans.com/reporttopdf.htm

If you want to use the Snapshot then you must ensure that each recipient has the viewer, that is why PDF is preferred.

JeffCoachman
0
 

Author Comment

by:shanej
ID: 22692637
Okay, thanks.  But how do I attach the PDF file you describe using SendObject?
0
 
LVL 23

Expert Comment

by:irudyk
ID: 22692693
You could attempt to output the report as an RTF, then use code to open the RTF document and resave it as a protected form (thus making it read-only) and then create a new email with the RTF file added as an attachment.  The code below could be modified to meet your specific needs.
Function SendReadOnlyReport()
 
'output report to RTF
DoCmd.OutputTo acOutputReport, "NameOfReport", acFormatRTF, "C:\NameOfReport.rtf"
 
'make RTF read-only
Dim wd As Object
Set wd = CreateObject("Word.Application")
With wd.Application
    .Documents.Open "C:\NameOfReport.rtf"
    .ActiveDocument.Protect 2, True, "EnterPasswordHere"
    .ActiveDocument.Save
    .ActiveDocument.Close
    .Quit
End With
 
'create/display email with RTF attachment
Dim ol As Object
Dim olNameSpace As Object
Dim olMessage As Object
Set ol = CreateObject("Outlook.Application")
Set olNameSpace = ol.GetNamespace("MAPI")
Set olMessage = ol.CreateItem(0)
olMessage.Attachments.Add "C:\NameOfReport.rtf"
olMessage.Display
 
Set olMessage = Nothing
Set olNameSpace = Nothing
Set ol = Nothing
 
End Function

Open in new window

0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 

Author Comment

by:shanej
ID: 22692742
Thanks!  Where do I place the code and how do I call the function?  Should it go behind the button I am using to call the SendObject method?  Here is the code as it appears currently:

Private Sub btnEmail_Click()
On Error GoTo Err_btnEmail_Click

    Dim stDocName As String
   
    stDocName1 = "POEmailReportShipTo"
    stDocName2 = "POEmailReportRemoveFrom"
    stDocName3 = "POEmailReportReleaseTo"
    stDocName4 = "POEmailReportWorkAddress"
   
    On Error Resume Next
       
    Me!POUser = CurrentUser
   
    DoCmd.RunCommand acCmdSaveRecord
   
    If Me!ShipRemoveRelease = "1" Then
        DoCmd.SendObject acReport, stDocName1, acFormatRTF, Me!VendorEmail, , , "NIS Purchase Order"
    End If
    If Me!ShipRemoveRelease = "2" Then
        DoCmd.SendObject acReport, stDocName2, acFormatRTF, Me!VendorEmail, , , "NIS Purchase Order"
    End If
    If Me!ShipRemoveRelease = "3" Then
        DoCmd.SendObject acReport, stDocName3, acFormatRTF, Me!VendorEmail, , , "NIS Purchase Order"
    End If
    If Me!ShipRemoveRelease = "4" Then
        DoCmd.SendObject acReport, stDocName4, acFormatRTF, Me!VendorEmail, , , "NIS Purchase Order"
    End If

Exit_btnEmail_Click:
    Exit Function

Err_btnEmail_Click:
    MsgBox Err.Description
    Resume Exit_btnEmail_Click
   
End Function
0
 
LVL 23

Assisted Solution

by:irudyk
irudyk earned 400 total points
ID: 22692782
Try revising you code as follows:

Private Sub btnEmail_Click()
On Error GoTo Err_btnEmail_Click
 
    Dim stDocName(4) As String
    
    stDocName(1) = "POEmailReportShipTo"
    stDocName(2) = "POEmailReportRemoveFrom"
    stDocName(3) = "POEmailReportReleaseTo"
    stDocName(4) = "POEmailReportWorkAddress"
    
    On Error Resume Next
        
    Me!POUser = CurrentUser
    
    DoCmd.RunCommand acCmdSaveRecord
    
    'output report to RTF
    DoCmd.OutputTo acOutputReport, stDocName(Me!ShipRemoveRelease), acFormatRTF, "C:\" & stDocName(Me!ShipRemoveRelease) & ".rtf"
 
    'make RTF read-only
    Dim wd As Object
    Set wd = CreateObject("Word.Application")
    With wd.Application
        .Documents.Open C:\" & stDocName(Me!ShipRemoveRelease) & ".rtf"
        .ActiveDocument.Protect 2, True, "EnterPasswordHere"
        .ActiveDocument.Save
        .ActiveDocument.Close
        .Quit
    End With
 
    'create/display email with RTF attachment
    Dim ol As Object
    Dim olNameSpace As Object
    Dim olMessage As Object
    Set ol = CreateObject("Outlook.Application")
    Set olNameSpace = ol.GetNamespace("MAPI")
    Set olMessage = ol.CreateItem(0)
    olMessage.To = Me!VendorEmail
    olMessage.Subject = "NIS Purchase Order"
    olMessage.Attachments.Add C:\" & stDocName(Me!ShipRemoveRelease) & ".rtf"
    olMessage.Display
    'or to send (you will likely get an Outlook security prompt appear)
    'olMessage.Send
    Set olMessage = Nothing
    Set olNameSpace = Nothing
    Set ol = Nothing
 
    'delete output file
    Kill C:\" & stDocName(Me!ShipRemoveRelease) & ".rtf"
 
Exit_btnEmail_Click:
    Exit Function
 
Err_btnEmail_Click:
    MsgBox Err.Description
    Resume Exit_btnEmail_Click
    
End Function

Open in new window

0
 

Author Comment

by:shanej
ID: 22692835
ShipRemoveRelease is an Access 97 frame control.  In my case, there are four options of reports that can be chosen using radio buttons inside the frame control.  Hence the four If, Then statements in my code sample that are used to choose and process the reports.  Am I correct in assuming that your code would be placed in its entirety inside each of my If, Then statements for each of the four possible reports with the lines of your code referencing my reports changed as necessary?
0
 
LVL 23

Expert Comment

by:irudyk
ID: 22692873
No, I am suggesting that you replace your entire Sub btnEmail_Click() with my version of Sub btnEmail_Click().
I use an array stDocName(4) to store and select the correct report name based upon the value of the ShipRemoveRelease.  So for ShipRemoveRelease values of 1, 2, 3 and 4 the report names would be:
    stDocName(1) = "POEmailReportShipTo"
    stDocName(2) = "POEmailReportRemoveFrom"
    stDocName(3) = "POEmailReportReleaseTo"
    stDocName(4) = "POEmailReportWorkAddress"
Also, I'm using DoCmd.OutputTo and not DoCmd.SendObject which is why I have a section called
     'create/display email with RTF attachment
wherein I've replicated the recipient and subject for the email in additon to the document to be attached.
0
 

Author Comment

by:shanej
ID: 22692887
Got it.  I will evaluate and let you know ASAP if I have any more questions or clarifications.  I appreciate your time and effort and I promise I'll get back to you.  I am in California, USA and have to hit the hay for an early day tomorrow.  So, I'll say goodnight for now.....

Shane
0
 

Accepted Solution

by:
shanej earned 0 total points
ID: 22694515
Thank you IRUDYK.  The code that actually works is pasted below.  I had to add a " (quote) prior to the C:\ in each line that referenced it.  You'll notice, too, that I had to change the Exit and End statements to reference the Sub and not a function.  These function references were left in there by mistake from previous trials of other code.

I do have one more question, though.  The Dim statement references stDocName(4).  My limited coding ability makes me think it should be a requirement to Dim stDocName(1), (2), and (3) as well.  Why isn't this necessary?



Private Sub btnEmail_Click()
On Error GoTo Err_btnEmail_Click
 
    Dim stDocName(4) As String
   
    stDocName(1) = "POEmailReportShipTo"
    stDocName(2) = "POEmailReportRemoveFrom"
    stDocName(3) = "POEmailReportReleaseTo"
    stDocName(4) = "POEmailReportWorkAddress"
   
    On Error Resume Next
       
    Me!POUser = CurrentUser
   
    DoCmd.RunCommand acCmdSaveRecord
   
    'output report to RTF
    DoCmd.OutputTo acOutputReport, stDocName(Me!ShipRemoveRelease), acFormatRTF, "C:\" & stDocName(Me!ShipRemoveRelease) & ".rtf"
 
    'make RTF read-only
    Dim wd As Object
    Set wd = CreateObject("Word.Application")
    With wd.Application
        .Documents.Open "C:\" & stDocName(Me!ShipRemoveRelease) & ".rtf"
        .ActiveDocument.Protect 2, True, "EnterPasswordHere"
        .ActiveDocument.Save
        .ActiveDocument.Close
        .Quit
    End With
 
    'create/display email with RTF attachment
    Dim ol As Object
    Dim olNameSpace As Object
    Dim olMessage As Object
    Set ol = CreateObject("Outlook.Application")
    Set olNameSpace = ol.GetNamespace("MAPI")
    Set olMessage = ol.CreateItem(0)
    olMessage.To = Me!VendorEmail
    olMessage.Subject = "NIS Purchase Order"
    olMessage.Attachments.Add "C:\" & stDocName(Me!ShipRemoveRelease) & ".rtf"
    olMessage.Display
    'or to send (you will likely get an Outlook security prompt appear)
    'olMessage.Send
    Set olMessage = Nothing
    Set olNameSpace = Nothing
    Set ol = Nothing
 
    'delete output file
    Kill "C:\" & stDocName(Me!ShipRemoveRelease) & ".rtf"
 
Exit_btnEmail_Click:
    Exit Sub

Err_btnEmail_Click:
    MsgBox Err.Description
    Resume Exit_btnEmail_Click
   
End Sub
0
 
LVL 26

Expert Comment

by:dannywareham
ID: 22694698
Not to hijack (do not accept as an answer)

The Dim statement simply tells Access/Jet to reserve a certain amount of memory for a variable.

In the case of an array, Dim stDocName(4) As String, you reserve a piece of memory for string information and declare that the array will have four seperate values.

You don't need to declare Dim stDocName(1) As String etc, as it's aready declared with the Dim stDocName(4) As String statement

Does that help?
0
 

Author Comment

by:shanej
ID: 22694783
Yeah... I guess I thought that since the other Dim statements are referencing discrete objects, that they would have to be individually "Dim'd."  Does this work because only one object at a time is used during the session, therfore allowing the "blanket Dim'g" of the variables that are available?  Sorry to be so nebulus in my writing, but this stuff is harder than h... for me to describe.
0
 
LVL 26

Assisted Solution

by:dannywareham
dannywareham earned 100 total points
ID: 22694832
The easiest way to think of it is that a Dim'd variable is a box.
The box can hold different types of things - numbers, letters, dates or a variety.

An array is a Dim'd variable with a number in brackets. This changes the box from a standard cardboard box into more of a chocolate box - with lots of little areas for your chocolates.

You only need to say "Hey Access, this is a box, but it'sgoing to have four chocolate areas in it".

So:

Dim myVariable as String
means "Access - there's a box and I'm gonna keep letters in it"

Whereas:

Dim myVariable (3) as String
means "Access - there's a box and I'm gonna keep letters in it, but there's going to be three little areas in that box"

Does that make sense?
0

Featured Post

10 Questions to Ask when Buying Backup Software

Choosing the right backup solution for your organization can be a daunting task. To make the selection process easier, ask solution providers these 10 key questions.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

As tax season makes its return, so does the increase in cyber crime and tax refund phishing that comes with it
Traditionally, the method to display pictures in Access forms and reports is to first download them from URLs to a folder, record the path in a table and then let the form or report pull the pictures from that folder. But why not let Windows retr…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…

634 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question