получить доступ к vba, объединить запрос одного столбца в один результат строки - PullRequest
0 голосов
/ 23 января 2019

У меня есть новая база данных, помогающая создавать документы для обработки заказа.

У меня есть запрос, настроенный только с одним столбцом результатов (Коды продуктов), определенным по заказу, выбранному в главной форме.

Мне нужно использовать эту информацию для именования моего файла aka

(Заказчик) (Продукт1) + (Продукт2) + (Продукт ....) (Расположение)

У меня есть код для генерации строки (Customer) (Product1) (Location), и я пытаюсь получить либо функцию сцепления, либо функцию цикла, либо что-то подобное, чтобы все продукты совпали с "+" междукаждая "строка".

У меня настроен запрос (Query1), чтобы дать мне точные данные, которые мне нужны ...

SELECT tblREF_Chemical.Abbr
FROM qry_AX_LineItems_DISTINCT INNER JOIN tblREF_Chemical ON 
qry_AX_LineItems_DISTINCT.ItemId = tblREF_Chemical.[Item Number]
GROUP BY tblREF_Chemical.Abbr, qry_AX_LineItems_DISTINCT.SALESID, 
tblREF_Chemical.[Proper Shipping Name]
HAVING (((qry_AX_LineItems_DISTINCT.SALESID)=[Forms]![frm_SalesOrderEntry]! 
[Combo617]) AND ((tblREF_Chemical.[Proper Shipping Name]) Is Not Null));

У меня настроена кнопка в главной формечтобы проверить вывод данных, а затем я собираюсь добавить в свой код код для имени файла DoCmd.Output.

Пока что единственный работающий код - это ...

Private Sub Command1492_Click()
Dim i As Integer

Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim SQL As String

Set db = CurrentDb
SL = [Forms]![frm_SalesOrderEntry]![Combo617]

SQL = "SELECT * FROM  ALL_SalesOrderItemsLineDates WHERE 
ALL_SalesOrderItemsLineDates.SALESID = '" & SL & "';"
Set rst = db.OpenRecordset(SQL)

For i = 0 To DCount("*", "ALL_SalesOrderItemsLineDates", 
 "ALL_SalesOrderItemsLineDates.SALESID = '" & [Forms]![frm_SalesOrderEntry]! 
[Combo617] & "'") - 1
 Debug.Print DLookup("[Abbr]", "[tblREF_Chemical]", "[Item Number]= '" & 
rst.Fields("ItemID") & "'")
 rst.MoveNext
Next i

rst.Close

End Sub

Кажется, я не могу добавить дополнительные операторы where в этом коде или использовать мой фактический запрос, или система выдает ошибки в строке кода db.OpenRecordset (ошибки 3061 и 3078).

Даже если игнорировать эти проблемы, вывод будет многострочным, и мне нужно, чтобы он использовался в одной строке текста для имени документа.

UPDATE1:

Я работаю с кодом, чтобы использовать мой запрос напрямую ...

Dim i As Integer

Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim SQL As String

Set db = CurrentDb
SL = [Forms]![frm_SalesOrderEntry]![Combo617]

SQL = "SELECT tblREF_Chemical.Abbr "
SQL = SQL & "FROM qry_AX_LineItems_DISTINCT INNER JOIN tblREF_Chemical ON qry_AX_LineItems_DISTINCT.ItemId = tblREF_Chemical.[Item Number] "
SQL = SQL & "GROUP BY tblREF_Chemical.Abbr, qry_AX_LineItems_DISTINCT.SALESID, tblREF_Chemical.[Proper Shipping Name] "
SQL = SQL & "HAVING ((qry_AX_LineItems_DISTINCT.SALESID)='" & SL & "'"
SQL = SQL & "AND ((tblREF_Chemical.[Proper Shipping Name]) Is Not Null));  "

Set rst = db.OpenRecordset(SQL)
Dim s As String

Do While rst(0) Is Not Null
   s = s & "+" & rst(0)
   rst.MoveNext
Loop
rst.Close
Debug.Print s

К сожалению, сейчас я получаю ошибку во время выполнения 3061 - Слишком мало параметров.Ожидаемый 1.

Я дважды проверил орфографию и выполнил запрос, чтобы быть уверенным, и независимо от того, сколько результатов получает запрос (работает должным образом), я все еще получаю эту ошибку.

ОБНОВЛЕНИЕ 2:

Благодаря большему количеству исследований я узнал, что запросы из-за отсутствия лучших слов могут иметь невидимое кодирование.Я обновляю свой код, чтобы удалить внутренний запрос из моего запроса, чтобы упростить объем «исследований», которые должен выполнять мой VBA.

Private Sub Command1492_Click()

Dim i As Integer

Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim SQL As String

Set db = CurrentDb
SL = [Forms]![frm_SalesOrderEntry]![Combo617]

SQL = "SELECT tblREF_Chemical.Abbr "
SQL = SQL & "FROM ALL_SalesOrderItemsLineDates INNER JOIN tblREF_Chemical ON ALL_SalesOrderItemsLineDates.ItemId = tblREF_Chemical.[Item Number] "
SQL = SQL & "GROUP BY tblREF_Chemical.Abbr, ALL_SalesOrderItemsLineDates.SALESID, tblREF_Chemical.[Proper Shipping Name]"
SQL = SQL & "HAVING ((ALL_SalesOrderItemsLineDates.SALESID)='" & SL & "'"
SQL = SQL & "AND ((tblREF_Chemical.[Proper Shipping Name]) Is Not Null));  "

Set rst = db.OpenRecordset(SQL)
Dim s As String

Do While rst(0) Is Not Null 'Debug error here!
   s = s & "+" & rst(0)
   rst.MoveNext
Loop
rst.Close
Debug.Print s

End Sub

К сожалению, я все еще получаю ошибку во время выполнения, но теперь это 424 объекта, требуемого, и отладка приводит меня к строке "Do While".

Я думаю этоэто шаг вперед, но все еще немного застрял.

Update3: Так как отладка переместила меня в строку «Do While», я вернулся к своему функциональному коду и заменил функцию цикла на код на основе целых чисел.

Спасибо, #Hasssed Папа!Ваш код был огромной помощью!Использовать вашу идею для строки, а не переходить к debug.print было гениально.

Приведенный ниже код заменяет мой код, начиная с которого у меня возникли проблемы.

Dim s As String

For i = 0 To DCount("*", "ALL_SalesOrderItemsLineDates", "ALL_SalesOrderItemsLineDates.SALESID = '" & SL & "'") - 1
 s = s & "+" & rst.Fields("Abbr")
 rst.MoveNext
Next i

 rst.Close
 Debug.Print s

Мои результаты отображаются только с одним икотацией.

+ CHA + DEEA + EEP + MEC + PERC + PM + PROP

В начале есть дополнительный знак "+", но я уверен, что смогу найти решение этой крошечнойпроблема.

Я надеюсь, что эти заметки могут помочь кому-то в будущем.Спасибо всем за помощь!

Ответы [ 2 ]

0 голосов
/ 23 января 2019

Ваша основная проблема - пропущенный пробел перед предложением AND in HAVING.

По этой причине удобочитаемости и удобства обслуживания рассмотрите возможность использования QueryDefs для параметризованных запросов (лучшая отраслевая практика) для запуска сохраненного запроса в VBA по нескольким причинам:

  1. Вы избегаете необходимости объединять или заключать в кавычки или экранировать литералы, эффективно отделяя код SQL от кода VBA (прикладного уровня).
  2. MS Access не позволит вам сохранить запрос с синтаксическими проблемами, но в строковых запросах VBA такие проблемы могут быть обнаружены во время выполнения.
  3. Движок MS Access компилирует и кэширует сохраненные запросы в соответствии с наилучшим планом выполнения, что особенно помогает для агрегированных запросов с объединениями. Вот почему сохраненные запросы обычно более эффективны, чем строковые запросы VBA, выполняемые на лету.

SQL (сохранить ниже как сохраненный запрос)

В запросе теперь используются псевдонимы таблиц, а условия HAVING перемещены в WHERE, поскольку агрегат не используется.

PARAMETERS idparam LONG;
SELECT t.Abbr
FROM qry_AX_LineItems_DISTINCT q
INNER JOIN tblREF_Chemical t ON q.ItemId = t.[Item Number]
WHERE (((q.SALESID) = [idparam]) 
  AND  ((t.[Proper Shipping Name]) Is Not Null))
GROUP BY t.Abbr, q.SALESID, t.[Proper Shipping Name];

* 1028 VBA *

Dim db As DAO.Database, qdef AS DAO.QueryDef, rst As DAO.Recordset
Dim SQL As String, s As String

Set db = CurrentDb
' INITIALIZE SAVED QUERY
Set qdef = db.QueryDefs("mySavedQuery")
' BIND PARAMETER
qdef![idparam] = [Forms]![frm_SalesOrderEntry]![Combo617]
' OPEN RECORDSET
Set rst = qdef.OpenRecordset()

Do While rst(0) Is Not Null
   s = s & "+" & rst(0)
   rst.MoveNext
Loop
rst.Close

Debug.Print s
Set rst = Nothing: Set qdef = Nothing: Set db = Nothing
0 голосов
/ 23 января 2019
Private Sub Command1492_Click()
Dim i As Integer

Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim SQL As String

Set db = CurrentDb
SL = [Forms]![frm_SalesOrderEntry]![Combo617]
SQL = "SELECT tblREF_Chemical.Abbr "
SQL = SQL & "FROM qry_AX_LineItems_DISTINCT INNER JOIN tblREF_Chemical ON "
SQL = SQL & "qry_AX_LineItems_DISTINCT.ItemId = tblREF_Chemical.[Item Number] "
SQL = SQL & "GROUP BY tblREF_Chemical.Abbr, qry_AX_LineItems_DISTINCT.SALESID, "
SQL = SQL & "tblREF_Chemical.[Proper Shipping Name] "
SQL = SQL & "HAVING (((qry_AX_LineItems_DISTINCT.SALESID)='" &  SL & "'"  'edit here
SQL = SQL & "AND ((tblREF_Chemical.[Proper Shipping Name]) Is Not Null));  "  


Set rst = db.OpenRecordset(SQL)
Dim s as string

Do While rst(0) is not null
   s = s & "+" & rst(0)
   rst.MoveNext
Loop
rst.Close
Debug.print s
End Sub
...