Script to Export SO

SUGGESTED

I'm working on a button script ("Execute on Server" selected, MAS 200) that will export a PDF of a Sales Order to a specific location without prompting the user. I'm running into some strange issues and was hoping someone has seen some of these things before. First, here is my script so far:

'Script to "export" SO to file

'Init VARs
sSONum = ""

dim path
path = "\\fileserver\Sage_Server\email_files\"

nOutputFormat = 0
sOutputPath = ""

retVal = oBusObj.GetValue("SalesOrderNo$",sSONum)

Set oSOPrint = oSession.AsObject(oSession.GetObject("SO_SalesOrderPrinting_rpt"))

retVal = oSOPrint.SetOptions(options)
oSOPrint.ReportType = 6

retval = oSOPrint.InitReportEngine()

retVal = oSOPrint.SelectReportSetting("SOFORM")

nOutputFormat = 5
sOutputPath = path & "Order_" & sSONum & ".pdf"
retVal = oSession.AsObject(oSession.UI).MessageBox("",sOutputPath)

retval = oSOPrint.SetExportOptions(nOutputFormat, sOutputPath)

retVal = oSOPrint.ProcessReport("EXPORT")

retVal = oSession.AsObject(oSession.UI).MessageBox("",osession.lasterrormsg)

The strange things that are happening is the sOutputPath is displaying with no "\" and where the "\" should be, there are new lines. So instead of "\\fileserver\Sage_Server\email_files\Order_123456.pdf", I'm getting:

fileserver

Sage_Server

email_files

Order_123456.pdf

No matter how I add quotes or additional backslashes, I can't seem to get it to display properly. I'm assuming that's part of the problem of it not exporting the PDF.

The other strange thing is that the oSession.LastErrorMsg is displaying as: "Module P/R is not on file." We DON'T have the payroll module, but that shouldn't even be trying to use that module. Hopefully it's something simple that's wrong in my code (I did a lot of reverse engineering of it from various semi-related posts on here). Thanks in advance!

  • 0

    I'm making progress. I've found that I can't declare a variable with backslashes and then reuse that. Manually setting the "oSOPrint.SetExportOptions" with "5" and "\\fileserver....." seems to work. Now my issue is after it exports the form, it throws an error saying "Record '0012108' in 'C:\Sage\Sage 100 Advanced.....\SO_SalesOrderHeader.M4T' is in use by another task.

    How can I prevent that? Also, if there are changes to any lines that aren't saved, how can I make this button script prompt the user to save changes (just like it does when you click the built-in 'Print Order')? 

  • 0

    Here's where I am so far. This is creating the SO form and filing it away, but there is a 'record in use' error after it runs.

    'Script to "export" SO to file

    'Init VARs
    sSONum = ""

    retVal = oBusObj.GetValue("SalesOrderNo$",sSONum)

    Set oSOPrint = oSession.AsObject(oSession.GetObject("SO_SalesOrderPrinting_rpt"))

    retVal = oSOPrint.SelectReportSetting("SOFORM")
    oSOPrint.QuickPrint = sSONum
    retVal = oSOPrint.SetOptions(options)
    oSOPrint.ReportType = 6

    retval = oSOPrint.InitReportEngine()

    retval = oSOPrint.SetExportOptions(5, "\\fileserver\share\Sage_Server\email_files\Order_" & sSONum & ".pdf")
    retVal = oSOPrint.ProcessReport("EXPORT")

    retVal = oSession.DropObject("SO_SalesOrderPrinting_rpt")

  • 0 in reply to chuntley87

    What happens if you comment out the DropObject()  line? 

  • 0 in reply to Alnoor

    Same issue. Error about the record being in use with no option other than "End" which closes the Sales Order window.

  • 0 in reply to chuntley87

    When you print using the SO printing feature a "printed" flag is saved to the order... but you have the order open still, so the change is blocked.

  • 0 in reply to Kevin M

    Makes sense. Is there any way around that? Either a way to "save and exit" the order via scripting, or a different way to export a PDF of the order without calling the "SalesOrderPrinting_rpt" object?

  • 0 in reply to chuntley87

    Can you possibly give us some background on the objective of the project?

    If the underlying premise is these are not new orders and don't need any further saving then your button script will work in S/O Inquiry and therefore you could condition it like this:

    If oSession.StartProgram = "SO_SALESORDERINQUIRY_UI" Then 

    You could run it from the S/O Quote Order History screen for that matter. (For one project, I actually have it running myself from P/O Entry but the purpose is different.)

    But if it's not true and you are trying to export orders as they are being created (or have pending changes to save for an existing order), you could try testing your code by shifting it to a Table PostWrite event script. Just condition the script to initially run in a test company while you test in the test company - e.g.

    If oSession.CompanyCode = "TST" Then 

    Hope that helps.

  • 0 in reply to Alnoor

    Yes, background helps understand the goals.  It's easy to get bogged down in technical details when an alternative solution may be best.

    An external reporting solution may be easier to deal with, instead of using Sage programs in a way they were not designed to function.

  • 0 in reply to Alnoor

    First, thank you Alnoor and Kevin for the feedback and help.

    What I'm trying to do is create a better way of emailing Sales Orders/Quotes to our customers. Here's the workflow of the script:

    1. User clicks "Email Order" button on SO Totals tab
    2. This opens a dialog box that has a few UDFs. 
    3. There is a "To" email address field which defaults from the header email, but can be changed and multiple email addresses can be entered, separated by a comma
    4. There is a "Body" UDF where the user can enter anything they wish to be in the body of the email
    5. There is another button that opens another dialog where the user can add additional attachments to the email.
    6. There is a button labeled "Send" that actually fires off the export of the SO PDF and sends the email with all of the variables defined in the previous steps. 

    What I'm trying to fix by doing this is a few things. First, by sending the email via a custom script, I can actually send the email using the user's email account, so that the email shows in their sent folder and they get any bounce backs (this is a huge issue for us, because even though Paperless Office emailing lets you change the "reply" email address to be the user's, bounces never go there and some customers' email programs doesn't respect the "reply" email and only shows the authenticated address, in our case a generic "no-reply@" email address). The script looks up the user, returns the user's email address, and then looks up their password from a UDT. Second, it lets you add a message to the email, so you can explain or instruct the customer within the email, and not rely on a comment line within the order. Third, it lets you attach supporting documents along with the order. Fourth, it is all on a per order basis, not company wide (what I mean by that is if Joe sends an email from the Paperless Office, the next time anybody in the company goes to send one, they have to remember to change the settings, because Joe's settings will be the 'default'). 

    The script actually works right now, it just throws that error. Even after that error, it exports the PDF correctly and sends the email correctly, it just crashes the SO window (and I would never put code into production that has an error "by design"). 

    Hope this helps explain my reason for the script. I would also need to put a way to prompt to save the order before sending as well, in the case of new orders or orders with unsaved changes. 

  • 0 in reply to chuntley87

    If it helps, here is the script so far (I haven't tied in the UDT with email passwords yet, so I just have my password defined). I haven't put too much error checking or anything in yet either. 

    'Script to "export" SO to file and send email
    On Error Resume Next

    'Init VARs
    sSONum = ""
    sOrderType = ""
    sOTName = ""
    sOrderDate = ""
    sEmail = ""
    sBody = ""
    sFirstName = ""
    sLastName = ""
    sFromName = ""
    sFromEmail = ""
    sAttach2 = ""
    sAttach3 = ""
    sAttach4 = ""
    sAttach5 = ""

    Set oUserInfo = oSession.AsObject(oSession.GetObject("SY_User_svc"))
    retVal = oUserInfo.Find(oSession.UserKey)

    retVal = oUserInfo.GetValue("FirstName$",sFirstName)
    retVal = oUserInfo.GetValue("LastName$",sLastName)
    retVal = oUserInfo.GetValue("EmailAddress$",sFromEmail)
    sFromName = sFirstName & " " & sLastName

    retVal = oBusObj.GetValue("SalesOrderNo$",sSONum)
    retVal = oBusObj.GetValue("OrderDate$",sOrderDate)
    retVal = oBusObj.GetValue("UDF_EMAILTO$",sEmail)
    retVal = oBusObj.GetValue("UDF_EMAILMSG$",sBody)
    retVal = oBusObj.GetValue("UDF_ATTACH2$",sAttach2)
    retVal = oBusObj.GetValue("UDF_ATTACH3$",sAttach3)
    retVal = oBusObj.GetValue("UDF_ATTACH4$",sAttach4)
    retVal = oBusObj.GetValue("UDF_ATTACH5$",sAttach5)

    retVal = oBusObj.GetValue("OrderType$",sOrderType)
    if sOrderType = "Q" or sOrderType = "P" then
    sOTName = "Quote_"
    else
    sOTName = "SalesOrder_"
    end if

    'export PDF

    Set oSOPrint = oSession.AsObject(oSession.GetObject("SO_SalesOrderPrinting_rpt"))

    retVal = oSOPrint.SelectReportSetting("WPL SO")
    oSOPrint.QuickPrint = sSONum
    retVal = oSOPrint.SetOptions(options)
    oSOPrint.ReportType = 6

    retval = oSOPrint.InitReportEngine()

    retval = oSOPrint.SetExportOptions(5, "\\lx-syn\share\Sage_Server\email_files\" & sOTName & sSONum & ".pdf")
    retVal = oSOPrint.ProcessReport("EXPORT")

    oSOPrint.Cleanup()
    oSOPrint.DropObject()

    retVal = oSession.DropObject("SO_SalesOrderPrinting_rpt")

    'begin send email

    EmailSubject = "Attached is " & sOTName & sSONum & ", dated " & sOrderDate
    EmailBody = sBody
    sAttach1 = "\\lx-syn\share\Sage_Server\email_files\" & sOTName & sSONum & ".pdf"


    Const SMTPServer = "smtp.gmail.com""
    Const SMTPPassword = "Password here. will be looked up from UDT"
    Const SMTPSSL = True
    Const SMTPPort = 465

    Const cdoSendUsingPickup = 1 'Send message using local SMTP service pickup directory.
    Const cdoSendUsingPort = 2 'Send the message using SMTP over TCP/IP networking.

    Const cdoAnonymous = 0 ' No authentication
    Const cdoBasic = 1 ' BASIC clear text authentication
    Const cdoNTLM = 2 ' NTLM, Microsoft proprietary authentication

    ' First, create the message

    Set objMessage = CreateObject("CDO.Message")
    objMessage.Subject = EmailSubject
    objMessage.From = """" & sFromName & """ <" & sFromEmail & ">"
    objMessage.To = sEmail
    objMessage.TextBody = EmailBody
    objMessage.AddAttachment sAttach1
    objMessage.AddAttachment sAttach2
    objMessage.AddAttachment sAttach3
    objMessage.AddAttachment sAttach4
    objMessage.AddAttachment sAttach5

    ' Second, configure the server

    objMessage.Configuration.Fields.Item _
    ("">schemas.microsoft.com/.../sendusing") = 2

    objMessage.Configuration.Fields.Item _
    ("">schemas.microsoft.com/.../smtpserver") = SMTPServer

    objMessage.Configuration.Fields.Item _
    ("">schemas.microsoft.com/.../smtpauthenticate") = cdoBasic

    objMessage.Configuration.Fields.Item _
    ("">schemas.microsoft.com/.../sendusername") = sFromEmail

    objMessage.Configuration.Fields.Item _
    ("">schemas.microsoft.com/.../sendpassword") = SMTPPassword

    objMessage.Configuration.Fields.Item _
    ("">schemas.microsoft.com/.../smtpserverport") = SMTPPort

    objMessage.Configuration.Fields.Item _
    ("">schemas.microsoft.com/.../smtpusessl") = SMTPSSL

    objMessage.Configuration.Fields.Item _
    ("">schemas.microsoft.com/.../smtpconnectiontimeout") = 60

    objMessage.Configuration.Fields.Update

    ' Now send the message!

    objMessage.Send

    'Confirmation message

    retVal = oSession.AsObject(oSession.UI).MessageBox("","Email sent successfully!")