+ Start a Discussion
mat_tone_84mat_tone_84 

upload file into opportunity with visual basic 6

Some time I have in the desktop some file for upload into opportunities.

 

I'm studying a program in vb6 for clicking on file on the desktop with right click and chose the menu "upload to salesforce".

After, the user will be write the id of opportunities, and the work as done!!

I will have my file on desktop into SF; in this way is more fast than upload manually into SF and login etc...

 

I'm able to loggin into sf and update field, but I'm not able to upload file, maybe I have to create a field with bloob or something similar....

Anyone can help me ?

I'm looking on discussion boards but I find something only for vb.net .

 

thanks!

 

RickNTARickNTA

Have you figured this out?  If not, post back here and I'll try to find time to help out - we solved this recently with VBA; will work with VB also.

gv007gv007

Rick can you post some steps or sample code ,uploading process from VB.Did you faced any limitation in this or you can upload whatever you want based on sfdc org limit.?.

Thanks

Gopi

RickNTARickNTA

I'll try to post some info and code soon - very busy now so can't today. 

mat_tone_84mat_tone_84

thanks

we'll wait for you

RickNTARickNTA

OK, guys here's some VBA code.  I've included a calling function and two supporting functions,
with some extraneous stuff cut out, but leaving in more than you may want, including some notes
on different approaches when we figured this out 6 months ago.  For login and etc. we use the  
Salesforce3 and SFC_Base3 classes from scrappydog in this forum, which provide a wrapper
for the Office Toolkit API (and were originally for VB6).  See notes inline for size limts, basic
flow, etc.  I guess we don't have a way to attach files here so I'm just pasting the whole thing below.
Good luck!

'***********************************************************************************
' NAME:       UploadAttachToSFOppRN()
' PURPOSE:    Upload an file as an Attachment to the SFDC Opportunity for the current
'               Account.  Intended primarily to use for PDF files but basic code
'               works with any file type.
' INPUTS:     strOppID - SFDC OppID
'             strPath - like C:\VSales\rick\Proposal\RFP Test\
'             strFile - filename with ext.
'             strSNAcctNo - Account Number for logging (could use CurrentAcctNo, but this is safer)
' RETURNS:    string with AttachmentID
' CALLED BY:  cmdUploadAttach_Click
' MODIFIED:   07/20/10 JG
' CREATED:    01/27/10 RN
' NOTE:       SF limits for Attachments: max 5MB, 1.5MB for Solution att.,
'               3MB for email att.
'             TODO: add check for file size!
'             Could make this generic - pass in ParentID and use for any object
'               that supports Attachments (Account, Campaign, Case, Contact, Contract,
'             Opportunity, Product2, Solution)
'***********************************************************************************
Public Function UploadAttachToSFOppRN(strOppID As String, strPath As String, _
                                    strFile As String, strSNAcctNo As String) As String

On Error GoTo Proc_Err
ERH_PushStack_TSB "UploadAttachToSFOppRN"

  Dim oSFSession As Salesforce3  ' Mike at KT's updated V3 version of Ron Hess's CSession
 
  Dim qrsOpp As QueryResultSet3   ' used to get Opp Name for MsgBox
  Dim Row As SObject3             ' used to get Opp Name for MsgBox
 
  Dim oAtt As SObject3          ' Attachment object
 
  ' vars used to encode binary file to Base64 for upload
  Dim arrFileData() As Byte     ' byte array for file data
  Dim strBase64 As String       ' Base64-encoded string created from byte array
 
  ' vars used to get Opp Name for MsgBox
  Dim strOppName As String
  Dim oIDs(0) As String         ' array of OppIDs (we only get 1)
    
  'Initialize return value
  UploadAttachToSFOppRN = ""
 
  ' Basic flow:
    ' log in to SF
    ' encode file to Base64
    ' create (upload) Attachment to Opp
    ' check success and inform user (and add entry to Action log)

' ######################################################################
' LOGIN TO SALESFORCE
' **********************************************************************
  Set oSFSession = LogInToSalesforce
  If oSFSession Is Nothing Then
    'Could not log in to Salesforce, so exit Proc
    GoTo Proc_Exit
  End If
 
' ######################################################################
' ENCODE FILE TO Base64
' **********************************************************************
  ' Attachment Body must be encoded as Base64
  ' First have to parse the binary file (PDF, etc.) into bytes
  ' Call function to fill arrFileData (passed ByRef) with bytes from
  ' binary file
  Call ReadByteArray(strPath & strFile, arrFileData)
 
  ' Call function to convert/encode arrFileData to Base64 string (using
  ' XML Doc!)
  strBase64 = EncodeBase64(arrFileData)
' **********************************************************************
' end ENCODE FILE TO Base64
' ######################################################################
 
' ######################################################################
' CREATE ATTACHMENT FOR SFDC OPP
' **********************************************************************
  ' Create Attachment object instance, set basic fields to link file to Opp,
  ' "commit" object record (create in SF), then make sure it worked
 
  ' This method is for a single record (see below for "batch" method)
  ' Instantiate a blank object
  ' This uses the session we opened above; CreateEntity is just CreateObject
  ' method of sfAPI object, which is SForceSession3 object of SF_MSApi3.dll
  ' (SForceOfficeToolkit)...
  Set oAtt = oSFSession.CreateEntity("Attachment")
  ' Populate object fields
  oAtt("Name") = strFile
  ' link to the OppID we got from SFDC when Account was created
  oAtt("ParentID") = strOppID
  ' used to raise SF err:
  oAtt("IsPrivate") = False
  oAtt("Body") = strBase64
  ' for Create we don't use BodyLength - throws err if we do...
  'oAtt("BodyLength") = 3
  ' don't need this - gets set by SFDC to logged-in user
  'oAtt("OwnerID") = ??
  ' commit the object
  oAtt.Create
  ' "refresh the object to get server set values"
  ' From sforce_office_toolkit.pdf:
  '   "Client applications call Refresh to make sure that the local object
  '    instances contain the most recent data from the server."
  ' We're not using the object after this so I don't see a need to Refresh...
  ' and removing it seems to take about 30% off total processing time!
  'oAtt.Refresh
 
  ' get the AttachmentID, set as return value
  UploadAttachToSFOppRN = oAtt("ID")
 
  ' SAVE for now $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
  ' This is the "batch" method (see above for single record method) - but
  ' this (based on example in sforce_office_toolkit.pdf under Create API call)
  ' just uses an array with one member - so I don't see any advantage over the
  ' single record method... (batch is faster if you have mult. recs)

  '  'create using batch call
  '  Dim so(0) As SObject3
  '
  '  ' if we use this have to set up the session... (log in, etc., I guess)
  '  'Set sfAPI = New SForceSession3
  '  'Set so(0) = sfAPI.CreateObject("Attachment")
  '  Set so(0) = oSFSession.CreateEntity("Attachment")
  '  so(0)("Name") = strFileName
  '  so(0)("ParentID") = Me.OppID
  '  'RFP VSales Test
  '  'so(0)("ParentID") = "0066000000CzDwcAAF"
  '  so(0)("IsPrivate") = False
  '  so(0)("Body") = strBase64
  '  ' do we need this?
  '  'so(0)("OwnerID") = ??
  '  'call batch method
  '  oSFSession.DoCreate so
  '  'sfAPI.Create so, False
  '  'call batch refresh
  '  '????
  '  'sfAPI.Refresh so, False
    
  ' end SAVE for now $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
' **********************************************************************
' end CREATE ATTACHMENT FOR SFDC OPP
' ######################################################################
 
' ######################################################################
' CHECK SUCCESS AND INFORM USER
' **********************************************************************
  ' Check error state and notify user with details of success or failure
  ' (and add entry to Action log if success)
 
  ' last step above was oAtt.Create; check oAtt err now
  ' handle SF err in err handler since we get there anyhow in many cases
  If oAtt.Error <> NO_SF_ERROR Then GoTo Proc_Err
    
  ' We have success; notify user, including the file we uploaded and the
  ' Opp it was attached to, since there can be mult. Opps per Acct
  ' (especially in VSales' future...)
 
  ' *** Get Opp name using Retrieve method *****************************
  ' this basic approach is from sforce_office_toolkit.pdf under Retrieve
  ' - modified to match methods we use in frmAccountNew.cmdGetSFData_Click
 
  ' We use an array here only because the Retrieve method requires it -
  ' but we only get one Opp so we just use the (0) member
  oIDs(0) = strOppID
 
  Set qrsOpp = oSFSession.Retrieve("Name", oIDs, "Opportunity")
  ' handle SF err in err handler since we get there anyhow in many cases??
  If oSFSession.GetError <> NO_SF_ERROR Then GoTo Proc_Err
  'Debug.Print g_sfApi.ErrorMessage
 
  ' from sforce_office_toolkit.pdf under Retrieve:
    '    Dim v As Variant
    '    Dim s As SObject3
    '    For Each v In qr
    '      'loop through the results
    '      'cast to a sobject3 to see more helpful debug info
    '      Set s = v
    '      If s.Error <> NO_SF_ERROR Then
    '        'Debug.Print s.ErrorMessage
    '      Else
    '        'use the object
    '        'NOTE you cannot call async methods until this method returns
    '        s.Update
    '        strOppName = s("Name")
    '      End If
    '    Next v
    
  ' this is the basic approach we use to get field values from a qrs
  ' in frmAccountNew.cmdGetSFData_Click
  For Each Row In qrsOpp
    strOppName = Row("Name").Value
    ' do we need this? I think not (it's slow, for one thing)
    ' oOpp.Update
    ' only 1 Row, right??!
    'Exit For
  Next
  ' *** end Get Opp name using Retrieve method *****************************

  ' **********************************************************************
' end CHECK SUCCESS AND INFORM USER
' ######################################################################

Proc_Exit:
  On Error Resume Next
  Set oAtt = Nothing
  Set qrsOpp = Nothing
  Set oSFSession = Nothing
  DoCmd.Hourglass False
  ERH_PopStack_TSB
  Exit Function

Proc_Err:
  ' if we hit an err while creating the Att. in SF, provide info
  If oAtt.Error <> NO_SF_ERROR Then
    'mstrMsg = "Error - the file was NOT uploaded to Salesforce." _
          & vbCrLf & vbCrLf _
          & "Salesforce returned this error message:" _
          & vbCrLf & vbCrLf _
          & "    " & oAtt.ErrorMessage _
          & vbCrLf & vbCrLf & vbCrLf & vbCrLf _
          & "Please try again and contact Sales Ops if you need help."
    'MsgBox mstrMsg, vbExclamation, "Upload failed"
  Else
    ' TODO: what about:
    ' If oSFSession.GetError <> NO_SF_ERROR Then
    ERH_Handler_TSB
  End If
  Resume Proc_Exit
  Resume

End Function


'***********************************************************************************
' NAME:       ReadByteArray()
' PURPOSE:    Read a binary file into a byte array
' INPUTS:     strPath - path and filename to parse
'             ByRef arrData() - empty byte array to fill
' RETURNS:    arrData() - filled byte array
' CALLED BY:  UploadAttachToSFOpp()
' MODIFIED:
' CREATED:    01/28/10 RN
' NOTE:
'   from Tim Hastings - NonHostile.com
'   VB6: Read and Write Byte Arrays to Files in Visual Basic (Code Library)
'   http://www.nonhostile.com/howto-read-write-byte-arrays-files-vb6.asp
'***********************************************************************************
Sub ReadByteArray(ByVal strPath As String, ByRef arrData() As Byte)

On Error GoTo Proc_Err
ERH_PushStack_TSB "ReadByteArray"

  Dim lngFile As Long
 
  ' open the file
  lngFile = FreeFile
  Open strPath For Binary Access Read As lngFile
 
  ' allocate enough memory to read file in one go
  ReDim arrData(1 To LOF(lngFile)) As Byte
 
  ' read blob
  Get lngFile, , arrData
 
  ' close file
  Close lngFile
 
Proc_Exit:
  ERH_PopStack_TSB
  Exit Sub

Proc_Err:
  ERH_Handler_TSB
  Resume Proc_Exit
  Resume

End Sub


'***********************************************************************************
' NAME:       EncodeBase64()
' PURPOSE:    Encode a byte array as Base64 string
' INPUTS:     ByRef arrData() - byte array with file data
' RETURNS:    Base64 encoded string
' CALLED BY:  UploadAttachToSFOpp()
' MODIFIED:
' CREATED:    01/28/10 RN
' NOTE:
'   from Tim Hastings - NonHostile.com
'   VB6: Free, Easy and Quick Base64 Encoding and Decoding in Visual Basic
'   http://www.nonhostile.com/howto-encode-decode-base64-vb6.asp

'   There seem to be many ways to encode, including fairly simple inline code,
'   DLLs, 3rd-party stuff, etc., but it appears that inline is very slow for large
'   files, and DLLs just add another component to manage... this method uses MS XML,
'   which we already use for web service stuff, takes just a few lines, and seems
'   fast (<1 sec for 2 MB Excel file on Zippy2!)
'***********************************************************************************
Public Function EncodeBase64(ByRef arrData() As Byte) As String

On Error GoTo Proc_Err
ERH_PushStack_TSB "EncodeBase64"
   
  Dim objXML As MSXML2.DOMDocument
  Dim objNode As MSXML2.IXMLDOMElement
 
  ' help from MSXML
  Set objXML = New MSXML2.DOMDocument
 
  ' byte array to base64
  Set objNode = objXML.createElement("b64")
  objNode.DataType = "bin.base64"
  objNode.nodeTypedValue = arrData
  EncodeBase64 = objNode.Text

Proc_Exit:
  On Error Resume Next
  Set objNode = Nothing
  Set objXML = Nothing
  ERH_PopStack_TSB
  Exit Function

Proc_Err:
  ERH_Handler_TSB
  Resume Proc_Exit
  Resume

End Function

gv007gv007

thanks RICK.