Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Send an RTF as Read Only

Posted on 2008-10-10
12
Medium Priority
?
908 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 1600 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 400 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

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

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

The Windows Phone Theme Colours is a tight, powerful, and well balanced palette. This tiny Access application makes it a snap to select and pick a value. And it doubles as an intro to implementing WithEvents, one of Access' hidden gems.
Code that checks the QuickBooks schema table for non-updateable fields and then disables those controls on a form so users don't try to update them.
In Microsoft Access, learn how to “cascade” or have the displayed data of one combo control depend upon what’s entered in another. Base the dependent combo on a query for its row source: Add a reference to the first combo on the form as criteria i…
Add bar graphs to Access queries using Unicode block characters. Graphs appear on every record in the color you want. Give life to numbers. Hopes this gives you ideas on visualizing your data in new ways ~ Create a calculated field in a query: …

688 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