I'm using a VBA code in excel to pick some data and insert it into an Access DB. I need this for several tables.
The problem is: For some of those tables, I get an error like: "INSERT INTO syntax error". But, if I get the string the code generates and uses for inserting, and use it in SQL mode form Access, the query works just fine. So that doesn't make any sense. Here is a piece of it:
For j = 6 To lastrow
SQLStr = "INSERT INTO TENSILE(REFERENCE, REF_ID, POSITION, RATIO, YSL0, YSL90, YSL180, YSL270, YST0, YST90, YST180, YST270, UTSL0, UTSL90, UTSL180, UTSL270, UTST0, UTST90, UTST180, UTST270, EL0, EL90, EL180, EL270, ET0, ET90, ET180, ET270, ARL0, ARL90, ARL180, ARL270, ART0, ART90, ART180, ART270) SELECT '" & ws3.Cells(j, 1) & "', REF.ID,'" & ws3.Cells(j, 60).Value & "'"
For i = 61 To 93
SQLStr = SQLStr & "," & ws3.Cells(j, i).Value
Next i
SQLStr = SQLStr & " FROM REF WHERE REF.REFERENCE LIKE '" & ws3.Cells(j, 1) & "'"
ws3.Cells(7, 3).Value = SQLStr
MsgBox (SQLStr)
'rs.Open SQLStr, con, adOpenStatic, adLockOptimistic 'Opening the query
Next j
it's important to notice that this same structure is used for other tables and works normaly, like in:
For j = 6 To lastrow
SQLStr = "INSERT INTO METALOGRAPHY(REFERENCE, REF_ID, AUSTGRAINSIZE) SELECT '" & ws3.Cells(j, 1) & "',REF.ID ," & ws3.Cells(j, 18).Value & " FROM REF WHERE REF.REFERENCE LIKE '" & ws3.Cells(j, 1) & "'"
'MsgBox (SQLStr)
'ws3.Cells(2, 3).Value = SQLStr
rs.Open SQLStr, con, adOpenStatic, adLockOptimistic 'Opening the query
Next j
What is going wrong?
Have you considered changing how you are linked to the Access DB so that you could use a statement like:
db.execute SQLStr
This should solve your problem
The following code, is generating that error.
Set getList = Server.CreateObject("ADODB.Command")
getList.ActiveConnection=EV_WikiConn
getList.Prepared = true
getList.commandtext= "declare #Lookup table(Id int identity(1, 1) , SongTitle nvarchar(512) )
insert into #Lookup(SongTitle)select * from ( values ('Deuce')) as x(a)
select A.AlbumName, S.SongTitle , S.Writers , S.Vocals , S.SID , S.TheTime
from Albums A inner join Songs S on A.AID = S.AID inner join #Lookup L on L.SongTitle = S.SongTitle order by L.Id"
set rsList = getList.execute
while not rsList.eof ' Error is on this line here.
I added this code here
Set getList = Server.CreateObject("ADODB.Command")
getList.ActiveConnection=EV_WikiConn
getList.Prepared = true
getList.commandtext= "declare #Lookup table(Id int identity(1, 1) , SongTitle nvarchar(512) )
insert into #Lookup(SongTitle)select * from ( values ('Deuce'),('Strutter'),('Parasite')) as x(a)
select A.AlbumName, S.SongTitle , S.Writers , S.Vocals , S.SID , S.TheTime
from Albums A inner join Songs S on A.AID = S.AID inner join #Lookup L on L.SongTitle = S.SongTitle order by L.Id"
set rsList = getList.execute
If rsList.State <> adStateOpen Then
While rsList.State <> adStateOpen
Set rsList = rsList.NextRecordset
rsList.movenext
wend
end if
This makes it run, however, I only get one record, instead of the 10 that is in the actual form. So, this is not going to work, but wanted to show what I have tried so far.
OK, got it all figured out. below is the code that was used, with a few notes in the code, to show what I did to make it work.
Set getList = Server.CreateObject("ADODB.Command")
getList.ActiveConnection=EV_WikiConn
getList.Prepared = true
getList.commandtext = _
"SET NOCOUNT ON " & _
"declare #Lookup table(Id int identity(1, 1) , " & _
"SongTitle nvarchar(512) ) " & _
"insert into #Lookup(SongTitle)select * from " & _
"( values ('Hotter_Than_Hell'), ('Firehouse'), ('She'), " & _
"('Parasite'), ('Nothin''_To_Lose')) as x(a) " & _
"select A.AlbumName, S.SongTitle , S.Writers , S.Vocals , " & _
"S.SID , S.TheTime from Albums A inner join " & _
"Songs S on A.AID = S.AID inner join " & _
"#Lookup L on L.SongTitle = S.SongTitle order by L.Id"
' the SET NOCOUNT ON, was added, but did not resolve the issue, I just left it in.
' The next 3 lines is what fixed the issue.
While rsList.State <> adStateOpen
Set rsList = rsList.NextRecordset
Wend
While Not rsList.EOF%>
<%=rsList("SongTitle")%>
<%rsList.movenext
wend
rsList.Close
set rsList = nothing
Regardless of what the OP believes this is a duplicate of
ADODB.Recordset error '800a0e78' Operation is not allowed when the object is closed
If we analyse the original code revision (ignoring the hard wrap which will cause an error in VBScript)
Set getList = Server.CreateObject("ADODB.Command")
getList.ActiveConnection=EV_WikiConn
getList.Prepared = true
getList.commandtext= "declare #Lookup table(Id int identity(1, 1) , SongTitle nvarchar(512) )
insert into #Lookup(SongTitle)select * from ( values ('Deuce')) as x(a)
select A.AlbumName, S.SongTitle , S.Writers , S.Vocals , S.SID , S.TheTime
from Albums A inner join Songs S on A.AID = S.AID inner join #Lookup L on L.SongTitle = S.SongTitle order by L.Id"
set rsList = getList.execute
while not rsList.eof ' Error is on this line here.
You can see that the original issue is the lack of
SET NOCOUNT ON;
to stop the closed ADODB.Recordset object being returned for the initial INSERT operation.
The subsequent edits the OP makes confuses the issue, before this adding SET NOCOUNT ON; would have fix the problem without needing further changes.
The next revision is where the confusion begins (again, ignoring the hard wrap which will cause an error in VBScript)
Set getList = Server.CreateObject("ADODB.Command")
getList.ActiveConnection=EV_WikiConn
getList.Prepared = true
getList.commandtext= "declare #Lookup table(Id int identity(1, 1) , SongTitle nvarchar(512) )
insert into #Lookup(SongTitle)select * from ( values ('Deuce'),('Strutter'),('Parasite')) as x(a)
select A.AlbumName, S.SongTitle , S.Writers , S.Vocals , S.SID , S.TheTime
from Albums A inner join Songs S on A.AID = S.AID inner join #Lookup L on L.SongTitle = S.SongTitle order by L.Id"
set rsList = getList.execute
If rsList.State <> adStateOpen Then
While rsList.State <> adStateOpen
Set rsList = rsList.NextRecordset
rsList.movenext
wend
end if
Let's just dissect this part
If rsList.State <> adStateOpen Then
While rsList.State <> adStateOpen
Set rsList = rsList.NextRecordset
rsList.movenext
wend
end if
First the If and While loop do the same thing accept the While does it repeatedly until the condition is met, making the If completely irrelevant.
The While loop checks for the current state of the ADODB.Recordset which without SET NOCOUNT ON; is returned as adStateClosed (due to the INSERT operation). This is fine but by changing the While loop from
while not rsList.eof
to
While rsList.State <> adStateOpen
the condition has been changed and the While is no longer checking for rsList.EOF which would be the case when we are enumerating the ADODB.Recordset object. However, now it is only checking for the .State of rsList which once .NextRecordset is called will exit the loop as a open ADODB.Recordset object has been returned. Because the condition has been met the loop will only run once calling .MoveNext once and only returning one record.
So to summaries using
SET NOCOUNT ON;
initially would have negated this whole scenario but hey "I don't understand the code" apparently.
I have a macro in excel 2013 that is trying to connect to an Oracle database through "Microsoft ODBC for Oracle", the 32bit version, as the 64bit has issues for some reason. And though the query works from Toad, it returns no results in my macro.
I have tried shorter queries and they do return results making me think that this monster query cannot be appended correctly, but I have no way to test this.
My current situation is a giant and very ugly append to get this query into one long string to be executed by my ADOConnection.
SQLString = "SELECT LEVEL, "
SQLString = SQLString & "MSIL.SEGMENT1 ITEM, "
SQLString = SQLString & "MSIL.DESCRIPTION DESC_COMPONENT, "
SQLString = SQLString & "BIC.ITEM_TYPE, "
SQLString = SQLString & "BIC.SUPPLY_TYPE, "
SQLString = SQLString & "MSIL.PRIMARY_UOM_CODE UOM, "
SQLString = SQLString & "BIC.COMPONENT_QUANTITY, "
SQLString = SQLString & "item_attribute.ITEM_LENGTH, "
SQLString = SQLString & "item_attribute.ANGLE_LEFT, "
SQLString = SQLString & "item_attribute.ANGLE_RIGHT, "
SQLString = SQLString & "item_attribute.WT_HT_FLAG, "
SQLString = SQLString & "item_attribute.FABRICATION_NUMBER, "
SQLString = SQLString & "item_attribute.PANEL_WIDTH, "
SQLString = SQLString & "item_attribute.PANEL_HEIGHT, item_attribute.GLASS_DIM1, item_attribute.GLASS_DIM2, item_attribute.DIMENSION1, item_attribute.DIMENSION2, "
SQLString = SQLString & "item_attribute.DIMENSION3, item_attribute.DIMENSION4, item_Attribute.DIMENSION5 "
SQLString = SQLString & "FROM APPS.MTL_SYSTEM_ITEMS MSI, APPS.BOM_BILL_OF_MATERIALS BOM, APPS.BOM_INVENTORY_COMPONENTS_V BIC, APPS.MTL_SYSTEM_ITEMS MSIL, APPS.mtl_parameters mp, "
SQLString = SQLString & "APPS.MTL_ITEM_CATALOG_GROUPS_VL micg, (SELECT * FROM (SELECT msi.inventory_item_id, mde.element_name, "
SQLString = SQLString & "mdev.element_value "
SQLString = SQLString & "FROM APPS.mtl_parameters mp, APPS.mtl_system_items_b msi, APPS.MTL_ITEM_CATALOG_GROUPS_VL micg, APPS.MTL_DESCRIPTIVE_ELEMENTS mde, APPS.MTL_DESCR_ELEMENT_VALUES mdev "
SQLString = SQLString & "WHERE mp.organization_id = MSI.organization_id AND mp.organization_code = 'POR' "
SQLString = SQLString & "AND micg.ITEM_CATALOG_GROUP_ID = MSI.ITEM_CATALOG_GROUP_ID AND mde.ITEM_CATALOG_GROUP_ID = micg.ITEM_CATALOG_GROUP_ID "
SQLString = SQLString & "AND mdev.element_name = mde.element_name AND mdev.inventory_item_id = msi.inventory_item_id AND mde.element_name IN ('Length', "
SQLString = SQLString & "'Angle Left', 'Angle Right', 'Wt Ht Flag', 'Fabrication Number', 'Panel Width', 'Panel Height', 'Glass Dim 1', 'Glass Dim 2', "
SQLString = SQLString & "'Dimension 1', 'Dimension 2', 'Dimension 3', 'Dimension 4', 'Dimension 5')) PIVOT (MAX (Element_value) FOR (element_name) "
SQLString = SQLString & "IN ('Length' AS ITEM_LENGTH, 'Angle Left' AS ANGLE_LEFT, 'Angle Right' AS ANGLE_RIGHT, 'Wt Ht Flag' AS WT_HT_FLAG, "
SQLString = SQLString & "'Fabrication Number' AS FABRICATION_NUMBER, 'Panel Width' AS PANEL_WIDTH, 'Panel Height' AS PANEL_HEIGHT, 'Glass Dim 1' AS GLASS_DIM1, "
SQLString = SQLString & "'Glass Dim 2' AS GLASS_DIM2, 'Dimension 1' AS DIMENSION1, 'Dimension 2' AS DIMENSION2, 'Dimension 3' AS DIMENSION3, "
SQLString = SQLString & "'Dimension 4' AS DIMENSION4, 'Dimension 5' AS DIMENSION5)) ORDER BY inventory_item_id) Item_attribute WHERE 1 = 1 "
SQLString = SQLString & "AND item_Attribute.inventory_item_id(+) = msil.INVENTORY_ITEM_ID AND BOM.ASSEMBLY_ITEM_ID = MSI.INVENTORY_ITEM_ID "
SQLString = SQLString & "AND BOM.ORGANIZATION_ID = MSI.ORGANIZATION_id AND bom.bill_sequence_id = bic.bill_sequence_id AND NVL (bic.disable_date, SYSDATE) >= SYSDATE "
SQLString = SQLString & "AND BIC.component_ITEM_ID = MSIL.INVENTORY_ITEM_ID AND Bom.ORGANIZATION_ID = MSIL.ORGANIZATION_ID AND mp.organization_id = msi.organization_id "
SQLString = SQLString & "AND mp.organization_code = 'POR' "
SQLString = SQLString & "AND micg.ITEM_CATALOG_GROUP_ID = msi.ITEM_CATALOG_GROUP_ID AND MSI.ORGANIZATION_ID = (SELECT DISTINCT OOL.SHIP_FROM_ORG_ID "
'These two lines are the ones that have our variables
SQLString = SQLString & "FROM APPS.OE_ORDER_HEADERS_ALL OOH, APPS.OE_ORDER_LINES_ALL OOL, APPS.MTL_SYSTEM_ITEMS MSI1 WHERE OOH.ORDER_NUMBER = '" & OracleOrderNumber & "' "
SQLString = SQLString & "AND OOL.LINE_NUMBER = '" & OracleLineNumber & "' "
'----------------------------------------------------
SQLString = SQLString & "AND OOL.HEADER_ID = OOH.HEADER_ID AND MSI1.SEGMENT1 = OOL.ORDERED_ITEM AND MSI1.ORGANIZATION_ID = OOL.SHIP_FROM_ORG_ID) "
SQLString = SQLString & "CONNECT BY PRIOR BIC.COMPONENT_ITEM_ID = BOM.ASSEMBLY_ITEM_ID START WITH MSI.INVENTORY_ITEM_ID IN (SELECT MSI1.INVENTORY_ITEM_ID "
SQLString = SQLString & "FROM APPS.OE_ORDER_HEADERS_ALL OOH, APPS.OE_ORDER_LINES_ALL OOL, APPS.MTL_SYSTEM_ITEMS MSI1 "
'These two lines are the ones that have our variables...again
SQLString = SQLString & "WHERE OOH.ORDER_NUMBER = '" & OracleOrderNumber & "' "
SQLString = SQLString & "AND OOL.LINE_NUMBER = '" & OracleLineNumber & "' "
'----------------------------------------------------
SQLString = SQLString & "AND OOL.HEADER_ID = OOH.HEADER_ID AND MSI1.SEGMENT1 = OOL.ORDERED_ITEM AND MSI1.ORGANIZATION_ID = OOL.SHIP_FROM_ORG_ID)"
There original query in it's cleaned up form is here.
SELECT LEVEL,
MSIL.SEGMENT1 ITEM,
MSIL.DESCRIPTION DESC_COMPONENT,
BIC.ITEM_TYPE,
BIC.SUPPLY_TYPE,
MSIL.PRIMARY_UOM_CODE UOM,
BIC.COMPONENT_QUANTITY,
item_attribute.ITEM_LENGTH,
item_attribute.ANGLE_LEFT,
item_attribute.ANGLE_RIGHT,
item_attribute.WT_HT_FLAG,
item_attribute.FABRICATION_NUMBER,
item_attribute.PANEL_WIDTH,
item_attribute.PANEL_HEIGHT,
item_attribute.GLASS_DIM1,
item_attribute.GLASS_DIM2,
item_attribute.DIMENSION1,
item_attribute.DIMENSION2,
item_attribute.DIMENSION3,
item_attribute.DIMENSION4,
item_attribute.DIMENSION5
FROM APPS.MTL_SYSTEM_ITEMS MSI,
APPS.BOM_BILL_OF_MATERIALS BOM,
APPS.BOM_INVENTORY_COMPONENTS_V BIC,
APPS.MTL_SYSTEM_ITEMS MSIL,
APPS.mtl_parameters mp,
APPS.MTL_ITEM_CATALOG_GROUPS_VL micg,
( SELECT *
FROM (SELECT msi.inventory_item_id,
mde.element_name,
mdev.element_value
FROM APPS.mtl_parameters mp,
APPS.mtl_system_items_b msi,
APPS.MTL_ITEM_CATALOG_GROUPS_VL micg,
APPS.MTL_DESCRIPTIVE_ELEMENTS mde,
APPS.MTL_DESCR_ELEMENT_VALUES mdev
WHERE mp.organization_id = msi.organization_id
AND mp.organization_code = 'POR' -- Warehouse -- POR(Portland), ITM (Item Master), TAC (Tacoma), TEM (Temecula), CMP (Composites)
AND micg.ITEM_CATALOG_GROUP_ID =
msi.ITEM_CATALOG_GROUP_ID
AND mde.ITEM_CATALOG_GROUP_ID =
micg.ITEM_CATALOG_GROUP_ID
AND mdev.element_name = mde.element_name
AND mdev.inventory_item_id = msi.inventory_item_id
AND mde.element_name IN ('Length',
'Angle Left',
'Angle Right',
'Wt Ht Flag',
'Fabrication Number',
'Panel Width',
'Panel Height',
'Glass Dim 1',
'Glass Dim 2',
'Dimension 1',
'Dimension 2',
'Dimension 3',
'Dimension 4',
'Dimension 5'))
PIVOT
(MAX (Element_value)
FOR (element_name)
IN ('Length' AS ITEM_LENGTH,
'Angle Left' AS ANGLE_LEFT,
'Angle Right' AS ANGLE_RIGHT,
'Wt Ht Flag' AS WT_HT_FLAG,
'Fabrication Number' AS FABRICATION_NUMBER,
'Panel Width' AS PANEL_WIDTH,
'Panel Height' AS PANEL_HEIGHT,
'Glass Dim 1' AS GLASS_DIM1,
'Glass Dim 2' AS GLASS_DIM2,
'Dimension 1' AS DIMENSION1,
'Dimension 2' AS DIMENSION2,
'Dimension 3' AS DIMENSION3,
'Dimension 4' AS DIMENSION4,
'Dimension 5' AS DIMENSION5))
ORDER BY inventory_item_id) Item_attribute
WHERE 1 = 1
AND item_Attribute.inventory_item_id(+) = msil.INVENTORY_ITEM_ID
AND BOM.ASSEMBLY_ITEM_ID = MSI.INVENTORY_ITEM_ID
AND BOM.ORGANIZATION_ID = MSI.ORGANIZATION_id
AND bom.bill_sequence_id = bic.bill_sequence_id
AND NVL (bic.disable_date, SYSDATE) >= SYSDATE
AND BIC.component_ITEM_ID = MSIL.INVENTORY_ITEM_ID
AND Bom.ORGANIZATION_ID = MSIL.ORGANIZATION_ID
AND mp.organization_id = msi.organization_id
AND mp.organization_code = 'POR' -- Warehouse -- POR(Portland), ITM (Item Master), TAC (Tacoma), TEM (Temecula), CMP (Composites)
AND micg.ITEM_CATALOG_GROUP_ID = msi.ITEM_CATALOG_GROUP_ID
AND MSI.ORGANIZATION_ID =
(SELECT DISTINCT OOL.SHIP_FROM_ORG_ID
FROM APPS.OE_ORDER_HEADERS_ALL OOH,
APPS.OE_ORDER_LINES_ALL OOL,
APPS.MTL_SYSTEM_ITEMS MSI1
WHERE OOH.ORDER_NUMBER = '1483' --Oracle Sales Order Number
AND OOL.LINE_NUMBER = '1' -- Oracle Sales Order Line Number
AND OOL.HEADER_ID = OOH.HEADER_ID
AND MSI1.SEGMENT1 = OOL.ORDERED_ITEM
--AND OOL.ORDERED_ITEM LIKE '%*%'
AND MSI1.ORGANIZATION_ID = OOL.SHIP_FROM_ORG_ID)
CONNECT BY PRIOR BIC.COMPONENT_ITEM_ID = BOM.ASSEMBLY_ITEM_ID
START WITH MSI.INVENTORY_ITEM_ID IN
(SELECT MSI1.INVENTORY_ITEM_ID
FROM APPS.OE_ORDER_HEADERS_ALL OOH,
APPS.OE_ORDER_LINES_ALL OOL,
APPS.MTL_SYSTEM_ITEMS MSI1
WHERE OOH.ORDER_NUMBER = '1483' --Oracle Sales Order Number
AND OOL.LINE_NUMBER = '1' -- Oracle Sales Order Line Number
AND OOL.HEADER_ID = OOH.HEADER_ID
AND MSI1.SEGMENT1 = OOL.ORDERED_ITEM
--AND OOL.ORDERED_ITEM like '%*%'
AND MSI1.ORGANIZATION_ID = OOL.SHIP_FROM_ORG_ID)
And thoughts would be fantastic, I have tired multiple drivers and installs of Oracle, connection does not seem to be my issue, it is how the query is executed.
As asked for here is my connection code...
Private Const ConnectionString = "Driver={Microsoft ODBC for Oracle}; CONNECTSTRING=string; uid=APPSRO; pwd=APPSRO;"
' ADO Connection Global Variable - Declared here so that, once the connection is opened, it can be used by any part of the code'
Public ADOConn As Object
Private OracleOrder As ADODB.Recordset
Private Const AppName = "Oracle BOM Data"
Private Const Version = "v1.0.0"
Public Const BoxTitle = AppName & " " & Version
Public Function ADOOpen(ByRef ADOConn As Object) As Boolean
' Open the ADO connection to the database and link it to the Object we've been passed'
' Handle errors here'
On Error Resume Next
' Clear the Error table'
Err.Clear
' Create a new connection and link it to the Object passed in'
Set ADOConn = CreateObject("ADODB.Connection")
' Now open the ADO connection to the database'
ADOConn.Open ConnectionString
'ADOConn.Properties("PLSQLRSet") = True'
' Now check for errors. Err.Number will be zero if there's been no error' since we cleared the Error table
If Err.Number = 0 Then
' So if there's been no error, return true'
ADOOpen = True
Else
' Otherwise, return false'
ADOOpen = False
End If
End Function
Ok, here is the actual function using the connections we know work...
Public Function LoadOracleOrder(OracleOrderNumber As Double, OracleLineNumber As Double)
Dim SQLString As String
Dim TargetSheet As Worksheet
Dim TargetCell As Range
Dim SQLQuery As String
On Error Resume Next
SQLString = "MONSTROUS QUERY HERE"
Debug.Print SQLString
Set OracleOrder = ADOFetch(SQLQuery, ADOConn)
If Err.Number <> 0 Then
WarnMsgBox "Warning: Query failed." & Chr(10) & "Error No: " & Err.Number & Chr(10) & "Error Description: " & Err.Description, BoxTitle
Err.Clear
ElseIf OracleOrder.RecordCount = 0 Then
InfoMsgBox "Query Returned No Results.", BoxTitle
Else
Set TargetSheet = Nothing
Set TargetSheet = ThisWorkbook.Sheets("Oracle Order Data")
If TargetSheet Is Nothing Then
Set TargetSheet = ThisWorkbook.Sheets.Add
TargetSheet.Name = "Oracle Order Data"
End If
TargetSheet.Cells.ClearContents
TargetSheet.Range("A1") = "LEVEL"
TargetSheet.Range("B1") = "ITEM"
TargetSheet.Range("C1") = "DESC_COMPONENT"
TargetSheet.Range("D1") = "ITEM_TYPE"
TargetSheet.Range("E1") = "SUPPLY_TYPE"
TargetSheet.Range("F1") = "UOM"
TargetSheet.Range("G1") = "COMPONENT_QUANTITY"
TargetSheet.Range("H1") = "ITEM_LENGTH"
TargetSheet.Range("I1") = "ANGLE_LEFT"
TargetSheet.Range("J1") = "ANGLE_RIGHT"
TargetSheet.Range("K1") = "WT_HT_FLAG"
TargetSheet.Range("L1") = "FABRICATION_NUMBER"
TargetSheet.Range("M1") = "GLASS_DIM1"
TargetSheet.Range("N1") = "GLASS_DIM2"
TargetSheet.Range("O1") = "DIMENSION1"
TargetSheet.Range("P1") = "DIMENSION2"
TargetSheet.Range("Q1") = "DIMENSION3"
TargetSheet.Range("R1") = "DIMENSION4"
TargetSheet.Range("S1") = "DIMENSION5"
Set TargetCell = TargetSheet.Range("A2")
OracleOrder.MoveFirst
While Not OracleOrder.EOF
TargetCell.Value = OracleOrder.Fields(0).Value
TargetCell.Offset(0, 1).Value = OracleOrder.Fields(1).Value
TargetCell.Offset(0, 2).Value = OracleOrder.Fields(2).Value
TargetCell.Offset(0, 3).Value = OracleOrder.Fields(3).Value
TargetCell.Offset(0, 4).Value = OracleOrder.Fields(4).Value
TargetCell.Offset(0, 5).Value = OracleOrder.Fields(5).Value
TargetCell.Offset(0, 6).Value = OracleOrder.Fields(6).Value
TargetCell.Offset(0, 7).Value = OracleOrder.Fields(7).Value
TargetCell.Offset(0, 8).Value = OracleOrder.Fields(8).Value
TargetCell.Offset(0, 9).Value = OracleOrder.Fields(9).Value
TargetCell.Offset(0, 10).Value = OracleOrder.Fields(10).Value
TargetCell.Offset(0, 11).Value = OracleOrder.Fields(11).Value
TargetCell.Offset(0, 12).Value = OracleOrder.Fields(12).Value
TargetCell.Offset(0, 13).Value = OracleOrder.Fields(13).Value
TargetCell.Offset(0, 14).Value = OracleOrder.Fields(14).Value
TargetCell.Offset(0, 15).Value = OracleOrder.Fields(15).Value
TargetCell.Offset(0, 16).Value = OracleOrder.Fields(16).Value
TargetCell.Offset(0, 17).Value = OracleOrder.Fields(17).Value
TargetCell.Offset(0, 18).Value = OracleOrder.Fields(18).Value
TargetCell.Offset(0, 19).Value = OracleOrder.Fields(19).Value
Set TargetCell = TargetCell.Offset(1, 0)
OracleOrder.MoveNext
Wend
End If
On Error GoTo 0
End Function
ADO Fetch, as asked...
Public Function ADOFetch(SQLQuery As String, ByRef ADOConn As Object) As Object
' Takes an existing, open ADO connection and uses it to return a Recordset, Nothing if no data is returned, or False if there's an error
' Local Object for the Recordset
Dim ADORecSet As Object
' Handle errors internally
On Error Resume Next
' Clear the Error table
Err.Clear
' Set up the Recordset by executing the SQL query
Set ADORecSet = ADOConn.ExecuteSQL(SQLQuery)
' Now check for errors. Err.Number will be zero if there's been no error since we cleared the Error table
If Err.Number = 0 Then
' So if there's been no error, return the record set
Set ADOFetch = ADORecSet
End If
' And either way, clear our temporary Recordset
ADORecSet = Nothing
On Error GoTo 0
End Function
While I understand you resolved your syntax issue, I thought I might suggest two approaches for best practices moving forward:
EXPLICIT JOIN
Use the current ANSI-syntax in joining tables in your query. Right now, your SQL is using the older, deprecated implicit join (keys being used in WHERE clause) versus the current ANSI-standard with the explicit join (keys used in INNER JOIN...ON). While this makes no difference in the query optimizer in terms of performance (see SO post), using INNER JOIN tends to be more readable and maintainable especially if you have various WHERE conditions to manage. Below is an attempt to translate your query with the INNER JOIN clause. Please test before use (notice WHERE is more readable):
SELECT LEVEL,
MSIL.SEGMENT1 ITEM,
MSIL.DESCRIPTION DESC_COMPONENT,
BIC.ITEM_TYPE,
BIC.SUPPLY_TYPE,
MSIL.PRIMARY_UOM_CODE UOM,
BIC.COMPONENT_QUANTITY,
item_attribute.ITEM_LENGTH,
item_attribute.ANGLE_LEFT,
item_attribute.ANGLE_RIGHT,
item_attribute.WT_HT_FLAG,
item_attribute.FABRICATION_NUMBER,
item_attribute.PANEL_WIDTH,
item_attribute.PANEL_HEIGHT,
item_attribute.GLASS_DIM1,
item_attribute.GLASS_DIM2,
item_attribute.DIMENSION1,
item_attribute.DIMENSION2,
item_attribute.DIMENSION3,
item_attribute.DIMENSION4,
item_attribute.DIMENSION5
FROM APPS.MTL_SYSTEM_ITEMS MSI
INNER JOIN APPS.BOM_BILL_OF_MATERIALS BOM
INNER JOIN APPS.BOM_INVENTORY_COMPONENTS_V BIC
INNER JOIN APPS.MTL_SYSTEM_ITEMS MSIL
INNER JOIN APPS.mtl_parameters mp
INNER JOIN APPS.MTL_ITEM_CATALOG_GROUPS_VL micg
INNER JOIN
( SELECT *
FROM (SELECT msi.inventory_item_id,
mde.element_name,
mdev.element_value
FROM APPS.mtl_parameters mp,
INNER JOIN APPS.mtl_system_items_b msi
INNER JOIN APPS.MTL_ITEM_CATALOG_GROUPS_VL micg
INNER JOIN APPS.MTL_DESCRIPTIVE_ELEMENTS mde
INNER JOIN APPS.MTL_DESCR_ELEMENT_VALUES mdev
ON mp.organization_id = msi.organization_id AND
ON micg.ITEM_CATALOG_GROUP_ID = msi.ITEM_CATALOG_GROUP_ID AND
ON mde.ITEM_CATALOG_GROUP_ID = micg.ITEM_CATALOG_GROUP_ID AND
ON mdev.element_name = mde.element_name AND
ON mdev.inventory_item_id = msi.inventory_item_id
WHERE mp.organization_code = 'POR' -- Warehouse -- POR(Portland), ITM (Item Master), TAC (Tacoma), TEM (Temecula), CMP (Composites)
AND mde.element_name IN ('Length',
'Angle Left',
'Angle Right',
'Wt Ht Flag',
'Fabrication Number',
'Panel Width',
'Panel Height',
'Glass Dim 1',
'Glass Dim 2',
'Dimension 1',
'Dimension 2',
'Dimension 3',
'Dimension 4',
'Dimension 5'))
PIVOT
(MAX (Element_value)
FOR (element_name)
IN ('Length' AS ITEM_LENGTH,
'Angle Left' AS ANGLE_LEFT,
'Angle Right' AS ANGLE_RIGHT,
'Wt Ht Flag' AS WT_HT_FLAG,
'Fabrication Number' AS FABRICATION_NUMBER,
'Panel Width' AS PANEL_WIDTH,
'Panel Height' AS PANEL_HEIGHT,
'Glass Dim 1' AS GLASS_DIM1,
'Glass Dim 2' AS GLASS_DIM2,
'Dimension 1' AS DIMENSION1,
'Dimension 2' AS DIMENSION2,
'Dimension 3' AS DIMENSION3,
'Dimension 4' AS DIMENSION4,
'Dimension 5' AS DIMENSION5))
ORDER BY inventory_item_id) Item_attribute
ON item_Attribute.inventory_item_id(+) = msil.INVENTORY_ITEM_ID AND
ON BOM.ASSEMBLY_ITEM_ID = MSI.INVENTORY_ITEM_ID AND
ON BOM.ORGANIZATION_ID = MSI.ORGANIZATION_id AND
ON bom.bill_sequence_id = bic.bill_sequence_id AND
ON BIC.component_ITEM_ID = MSIL.INVENTORY_ITEM_ID AND
ON Bom.ORGANIZATION_ID = MSIL.ORGANIZATION_ID AND
ON mp.organization_id = msi.organization_id AND
ON micg.ITEM_CATALOG_GROUP_ID = msi.ITEM_CATALOG_GROUP_ID
WHERE 1 = 1
AND NVL (bic.disable_date, SYSDATE) >= SYSDATE
AND mp.organization_code = 'POR' -- Warehouse -- POR(Portland), ITM (Item Master), TAC (Tacoma), TEM (Temecula), CMP (Composites)
AND MSI.ORGANIZATION_ID =
(SELECT DISTINCT OOL.SHIP_FROM_ORG_ID
FROM APPS.OE_ORDER_HEADERS_ALL OOH
INNER JOIN APPS.OE_ORDER_LINES_ALL OOL
INNER JOIN APPS.MTL_SYSTEM_ITEMS MSI1
ON OOL.HEADER_ID = OOH.HEADER_ID AND
ON MSI1.SEGMENT1 = OOL.ORDERED_ITEM AND
ON MSI1.ORGANIZATION_ID = OOL.SHIP_FROM_ORG_ID
WHERE OOH.ORDER_NUMBER = '1483' --Oracle Sales Order Number
AND OOL.LINE_NUMBER = '1' -- Oracle Sales Order Line Number
--AND OOL.ORDERED_ITEM LIKE '%*%'
)
CONNECT BY PRIOR BIC.COMPONENT_ITEM_ID = BOM.ASSEMBLY_ITEM_ID
START WITH MSI.INVENTORY_ITEM_ID IN
(SELECT MSI1.INVENTORY_ITEM_ID
FROM APPS.OE_ORDER_HEADERS_ALL OOH
INNER JOIN APPS.OE_ORDER_LINES_ALL OOL
INNER JOIN APPS.MTL_SYSTEM_ITEMS MSI1
ON OOL.HEADER_ID = OOH.HEADER_ID AND
ON MSI1.SEGMENT1 = OOL.ORDERED_ITEM AND
ON MSI1.ORGANIZATION_ID = OOL.SHIP_FROM_ORG_ID
WHERE OOH.ORDER_NUMBER = '1483' --Oracle Sales Order Number
AND OOL.LINE_NUMBER = '1' -- Oracle Sales Order Line Number
--AND OOL.ORDERED_ITEM like '%*%'
)
EXTERNAL .SQL FILE
Because VBA does not allow strings across multiple lines without underscores and ampersands, consider avoiding the need for a long concatenation of the "giant" VBA string. Instead, read in an external .sql file into the VBA string.
This will allow effortless change of the SQL query as you only need to copy/paste from your database console into the .sql text file and your Excel macro will read in the latest version without worrying about adjusting commas, underscores, and ampersands. Save below script in a separate function and in your query function, LoadOracleOrder(), simply call it as: SQLString = ReadSQL():
Function ReadSQL() As String
On Error GoTo ErrHandle
Dim objFSO As Object, ofile As Object
Dim sqlFile As String, strSQL As String, dataLine As String
Dim readFile As Integer, i As Integer
Const ForReading = 1
' INITIALIZE OBJECTS
sqlFile = ActiveWorkbook.Path & "\OracleQuery.sql"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set ofile = objFSO.OpenTextFile(sqlFile, ForReading)
' OPEN FILE, READ LINES, CLOSE FILE
readFile = FreeFile()
Open sqlFile For Input As #readFile
strSQL = ""
Do While ofile.AtEndofStream <> True
strSQL = strSQL & ofile.ReadLine & vbNewLine
Loop
ReadSQL = strSQL
Close #readFile
ofile.Close
Set ofile = Nothing
Set objFSO = Nothing
Exit Function
ErrHandle:
MsgBox Err.Number & " - " & Err.Description, vbCritical
Set ofile = Nothing
Set objFSO = Nothing
Exit Function
End Function
Ok after running through issues that were overlooked due to my On Error Resume Next(thanks Tim), I found that I had a type mismatch, and I had a comma that should not have been in the sql (it had originally commented out but I must have changed it when appending the giant string).
Lastly, turns out there was a call to create a worksheet and then place the data in the project in which the macro was in (which is my personal file, not helpful.)
Thank you for your comments, and suggestions all of them helped me find the solution.