title: VBA program executing SAP RFCs works in Excel 2016 on-prem, but not in Office 365 (Run-time error 20080008...Bad Variant Type)
body: <p>Let me first say that I saw the other two threads that mentioned this issue <a href="https://stackoverflow.com/questions/56459823/sap-rfc-connection-with-vba-bad-variant-type">here</a> and <a href="https://stackoverflow.com/questions/14454574/sap-rfc-connection-bad-variant-type">here</a>, but they didn't help me solve my problem.</p>
  
  <p>I've been testing a program for several weeks in the on-prem Excel 2016 environment (32-bit) with no problems. My company is making the move to Office 365 soon, so I decided to test it over there as well. On that system, I'm getting a run-time error on the line <code>Functions.Connection = objConnection</code></p>
  
  <pre><code>Option Explicit
  Public Functions As SAPFunctionsOCX.SAPFunctions
  Private LogonControl As SAPLogonCtrl.SAPLogonControl
  Private objConnection As SAPLogonCtrl.Connection
  Public Func As SAPFunctionsOCX.Function
  Public Commit As SAPFunctionsOCX.Function
  Public TableFactory As SAPTableFactory
  Public silentLogon As Boolean
  Public tblReadTableOptions, tblReadTableFields, tblReadTableData As SAPTableFactoryCtrl.Table
  
  Sub ExtractProjectData()
      If objConnection Is Nothing Then LogonToSAP
      InitiateSAPVariables
      Set Func = Functions.Add("BBP_RFC_READ_TABLE")
      Set tblReadTableOptions = Func.Tables("OPTIONS")
      Set tblReadTableFields = Func.Tables("FIELDS")
      Set tblReadTableData = Func.Tables("DATA")
  
      'extract/transform data from SAP tables
  
  End Sub
  
  Function InitiateSAPVariables()
      Set Functions = Nothing
      Set TableFactory = Nothing
      Set Func = Nothing
      Set Functions = CreateObject("SAP.Functions")
      Set TableFactory = CreateObject("SAP.TableFactory.1")
      Functions.Connection = objConnection 'run-time error here in Office 365 but not in on-prem
  End Function
  
  Function LogonToSAP()
      Dim establishConnection As Boolean
      silentLogon = false
      Set LogonControl = CreateObject("SAP.LogonControl.1")
      Set objConnection = LogonControl.NewConnection
      objConnection.Client = "###"
      objConnection.Language = "EN"
      objConnection.SystemNumber = "##"
      objConnection.User = ""
      objConnection.Password = ""
      objConnection.HostName = "###############"
      objConnection.System = "###"
      objConnection.ApplicationServer = "###.###.#.##"
      establishConnection = objConnection.Logon(0, silentLogon)
  End Function
  </code></pre>
  
  <p>A quick check of objConnection tells me that logon was successful...so I know that part is working on 365. For some reason though, it doesn't like assigning the <code>Connection</code> property of the <code>Functions</code> SAPFunctionsOCX.SAPFunctions object in the 365 environment (please feel free to correct my verbiage on that...I know it's not quite right).</p>
  
  <p>Note that I'm not seeing any reference issues nor am I getting any compile errors in either environment. The first sign of trouble is on execution of <code>Functions.Connection = objConnection</code></p>
  
  <p>There's one more twist here and that is that I have another older VBA program that logs into SAP and runs remote function calls that doesn't use SAPFunctionsOCX.SAPFunctions, but rather declares variable R3 as <code>Public R3 As Object</code> and then sets R3 later in the logon code as <code>Set R3 = CreateObject("SAP.Functions")</code>...it does not use OCX. In other words, the old routine uses late binding. When the Functions object (R3 in this case) is set this way, I am able to run RFCs in both on prem and Office 365 environments.</p>
  
  <pre><code>Function LogonProdSAP(Optional SuppressLoginScreen As Boolean)
      Application.ScreenUpdating = False
      '**********************************************
      'Create Server object and Setup the connection for DEV
      '**********************************************
      Set R3 = CreateObject("SAP.Functions")
      If SuppressLoginScreen Then
          R3.Connection.System = "###"
          R3.Connection.HostName = "###################"
          R3.Connection.SystemNumber = "##"
          R3.Connection.Client = "###"
          R3.Connection.User = "##########"
          R3.Connection.Password = "#########"
          R3.Connection.Language = "EN"
  '        Call Logger("LogonProdSAP&gt;  " &amp; GetUserName)
      End If
      LogonProdSAP = R3.Connection.logon(0, SuppressLoginScreen)
      If LogonProdSAP &lt;&gt; True Then MsgBox ("Logon error"): Exit Function
  End Function
  </code></pre>
  
  <p>I could just go back to doing it this way, but I'd rather not have to reconfigure all of the code I just set up. In addition, I prefer binding early so Intellitype works to show all properties/methods available to that object. I'm sure there are other benefits as well.</p>
  
  <p>What do I have to do to get the early-binding technique to work on Office 365?</p>