Как выполнить запрос append в ms-доступе vba как часть транзакции. Vba access выполнить запрос


VBA Access SQL - делаем запрос из макросов

VBA Access SQL

Периодически я вижу, как пытаются найти информацию: а как можно сделать запрос через SQL и макросов VBA? Сегодня я постараюсь осветить данную область и рассказать про связь VBA Access SQL.

CurrentProject.Connection

Это один из самых простых способов для связи Access и БД, но для его реализации необходимо связать локальные таблицы и БД. (Более подробно можно почитать на вики про DSN) Для этого заходим в меню, как на скриншоте:

 

Выбираем пункт «База данных ODBC» и в появившемся окне выбираем «Создать связанную таблицу для связи с источником данных.», см. скриншот:

После этого появиться окно, в котором можно открыть уже существующее или создать новое соединение. При создании каждый должен самостоятельно ответить на кучу различных вопросов для подключения к своей БД. После этого необходимо выбрать это подключение и добавить необходимы таблицы. В Access такие таблицы будут выделяться специальной иконкой, см. скриншот.

Ну и для того, чтобы сделать запрос к БД средствами VBA Access SQL приведу вот такой небольшой пример:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

Set cnn = CurrentProject.Connection

Set rs = New ADODB.Recordset

strSQL = "SELECT * FROM test" 'Запрос

rs.Open strSQL, cnn 'Открытие связи с БД по запросу

col = 0

Do While col <= rs.Fields.Count - 1

ColName(col) = rs.Fields(col).Name 'Вывод названия колонок

col = col + 1

Loop

Do While Not rs.EOF

rw = rw + 1

For i = 0 To col - 1

ValueCol(rw, i) = rs.Fields(i) 'Вывод значения колонок

Next

rs.MoveNext 'Переход к следующей записи

Loop

rs.Close 'Закрытие связи с БД

Комментариями в программе я постарался отметить ключевые моменты. В массив ColName записываются названия колонок, а в массив ValueCol значения. Стоит отметить, что данные массивы необходимо первоначально объявить и всегда актуализировать по размерности при помощи Dim и ReDim, т.к. в большинстве своем они буду динамические.

dg13.net

Не удается выполнить запрос в Access через vba с длинным определением

У меня очень длинное определение запроса, которое работает, когда оно запускается в графическом интерфейсе Access. Я не хочу сохранять его как объект Query, который может случайно запустить конечный пользователь, поэтому я хочу запустить его через VBA. Когда я попытался запустить его с помощью DoCmd.RunSQL, он выдает ошибку:

«Для действия RunSQL требуется аргумент, состоящий из оператора SQL».

Когда я пытаюсь его mydatabase.Execute я получаю:

«Двигатель Microsoft Access не удается найти входную таблицу или запрос„“Убедитесь, что он существует и что его имя пишется правильно.».

Я сделал Debug.Print и скопировал вывод в Query в графическом интерфейсе Access, после очистки линии тормоза окно Immediate добавило, что запрос прошел нормально. Строка запроса составляет 5 293 символа. Любая помощь будет оценена по достоинству.

Dim dBase As Database Set dBase = CurrentDb() Dim stringSQL_3 As String stringSQL_3 = _ "INSERT INTO Measurement_Period_History (EMPLOYEE_NUMBER, PERIOD_START, PERIOD_END, DATE_REVIEWED, AVERAGE_HOURS, PERIOD_YEAR, PERIOD_TYPE_ID, FIRST_PAY_WEEK, LAST_PAY_WEEK) " & _ "SELECT FinalData.EMPLOYEE_NUMBER " & _ ",FinalData.START_PERIOD " & _ ",FinalData.END_PERIOD " & _ ",Now() AS DATE_REVIEWED " & _ ",IIF(FinalData.FLSA = 2, 40.00, SUM(FinalData.HOURS)/52) AS AVERAGE_HOURS " & _ ",Cint(FinalData.PERIOD_YEAR) AS PERIOD_YEAR " & _ ",FinalData.PERIOD_TYPE_ID " & _ ",FinalData.FIRST_PAY_WEEK " & _ ",FinalData.LAST_PAY_WEEK " stringSQL_3 = stringSQL_3 & _ "FROM (" & _ "SELECT MeasurementData.EMPLOYEE_NUMBER " & _ ",MeasurementData.FLSA " & _ ",MeasurementData.STARTING_HIRE_DATE " & _ ",MeasurementData.VARIABLE_EMPLOYEE " & _ ",MeasurementData.START_PERIOD " & _ ",MeasurementData.END_PERIOD " & _ ",MeasurementData.PERIOD_TYPE_ID " & _ ",MeasurementData.PRIOR_PERIOD_START " & _ ",MeasurementData.PERIOD_YEAR " & _ ",MeasurementData.FIRST_PAY_WEEK " & _ ",MeasurementData.LAST_PAY_WEEK " & _ ",IIf(IsNull(Payroll_History.HOURS), 0, Payroll_History.HOURS) AS HOURS " stringSQL_3 = stringSQL_3 & _ "FROM Payroll_History " & _ "RIGHT JOIN (" & _ "SELECT BaseData.EMPLOYEE_NUMBER " & _ ",BaseData.FLSA " & _ ",BaseData.STARTING_HIRE_DATE " & _ ",BaseData.VARIABLE_EMPLOYEE " & _ ",BaseData.START_PERIOD " & _ ",BaseData.END_PERIOD " & _ ",BaseData.PERIOD_TYPE_ID " & _ ",BaseData.PRIOR_PERIOD_START " & _ ",BaseData.PERIOD_YEAR " & _ ",DateAdd('d', 3, DateAdd('ww', - 52, DateAdd('d', - 2, DateAdd('ww', DateDiff('ww', 0, DateAdd('ww', IIf(DatePart('w', " & _ "BaseData.END_PERIOD) >= 5, 0, - 1), BaseData.END_PERIOD)), 0)))) AS FIRST_PAY_WEEK " & _ ",DateAdd('d', - 2, DateAdd('ww', DateDiff('ww', 0, DateAdd('ww', IIf(DatePart('w', BaseData.END_PERIOD) >= 5, 0, - 1), " & _ "BaseData.END_PERIOD)), 0)) AS LAST_PAY_WEEK " stringSQL_3 = stringSQL_3 & _ "FROM (" & _ "SELECT ElgEmployees.EMPLOYEE_NUMBER " & _ ",ElgEmployees.FLSA " & _ ",ElgEmployees.STARTING_HIRE_DATE " & _ ",ElgEmployees.VARIABLE_EMPLOYEE " & _ ",IIF(ElgEmployees.VARIABLE_EMPLOYEE = No, DateSerial(" & DatePickerYear & " - 1, 4, 1), " & _ "IIF(PeriodInfo.PRIOR_PERIOD_START IS NOT NULL, DateSerial(" & DatePickerYear & " - 1, DatePart('m', " & _ "PeriodInfo.PRIOR_PERIOD_START), 1), DateSerial(" & DatePickerYear & " - 1, DatePart('m', ElgEmployees.STARTING_HIRE_DATE), 1))) AS START_PERIOD " & _ ",IIF(ElgEmployees.VARIABLE_EMPLOYEE = No, DateAdd('d', - 1, DateSerial(" & DatePickerYear & ", 4, 1)), DateAdd('d', - 1, " & _ "IIF(PeriodInfo.PRIOR_PERIOD_START IS NOT NULL, DateSerial(" & DatePickerYear & ", DatePart('m', PeriodInfo.PRIOR_PERIOD_START), 1), " & _ "DateSerial(" & DatePickerYear & ", DatePart('m', ElgEmployees.STARTING_HIRE_DATE), 1)))) AS END_PERIOD " & _ "," & DatePickerYear & " AS PERIOD_YEAR " & _ ",PeriodInfo.PERIOD_TYPE_ID " & _ ",PeriodInfo.PRIOR_PERIOD_START " stringSQL_3 = stringSQL_3 & _ "FROM (" & _ "SELECT Employee.EMPLOYEE_NUMBER " & _ ",Employee.FLSA " & _ ",Employee.VARIABLE_EMPLOYEE " & _ ",IIf(Day(Employee.CURRENT_HIRE_DATE) = 1, Employee.CURRENT_HIRE_DATE, DateSerial(DatePart('yyyy', DateAdd('m', 1, " & _ "Employee.CURRENT_HIRE_DATE)), DatePart('m', DateAdd('m', 1, Employee.CURRENT_HIRE_DATE)), 1)) AS STARTING_HIRE_DATE " stringSQL_3 = stringSQL_3 & _ "FROM Employee " & _ "WHERE (" & _ "((Employee.EMPLOYEE_NUMBER)" & EmployeeNumberText & ") " & _ "AND ((IIf(Day(Employee.CURRENT_HIRE_DATE) = 1, Employee.CURRENT_HIRE_DATE, DateSerial(DatePart('yyyy', DateAdd('m', 1, " & _ "Employee.CURRENT_HIRE_DATE)), DatePart('m', DateAdd('m', 1, Employee.CURRENT_HIRE_DATE)), 1))) < DateAdd('y', - 1, DATE())) " & _ "AND ((Employee.CURRENT_TERMINATION_DATE) IS NULL) " & _ ") " & _ ") AS ElgEmployees " & _ "INNER JOIN (" & _ "SELECT Employee.EMPLOYEE_NUMBER " & _ ",IIF(Measurement_Period_History.PERIOD_YEAR <> " & DatePickerYear & " - 1, NULL, Measurement_Period_History.PERIOD_YEAR) AS PRIOR_PERIOD_YEAR " & _ ",IIF(Measurement_Period_History.PERIOD_YEAR <> " & DatePickerYear & " - 1, IIF(Employee.VARIABLE_EMPLOYEE = No, 2, 0), " & _ "IIF(Employee.VARIABLE_EMPLOYEE = No, 2, IIF(Measurement_Period_History.PERIOD_END < Employee.CURRENT_HIRE_DATE, 0, " & _ "IIF(Measurement_Period_History.AVERAGE_HOURS >= 30, 1, 0)))) AS PERIOD_TYPE_ID " & _ ",IIF(Measurement_Period_History.PERIOD_YEAR <> " & DatePickerYear & " - 1, NULL, IIF(Measurement_Period_History.PERIOD_END < " & _ "Employee.CURRENT_HIRE_DATE, NULL, Measurement_Period_History.PERIOD_END)) AS PRIOR_PERIOD_END " & _ ",IIF(Measurement_Period_History.PERIOD_YEAR <> " & DatePickerYear & " - 1, NULL, IIF(Measurement_Period_History.PERIOD_END < " & _ "Employee.CURRENT_HIRE_DATE, NULL, Measurement_Period_History.PERIOD_START)) AS PRIOR_PERIOD_START " stringSQL_3 = stringSQL_3 & _ "FROM Measurement_Period_History " & _ "RIGHT JOIN Employee ON Measurement_Period_History.EMPLOYEE_NUMBER = Employee.EMPLOYEE_NUMBER " & _ "WHERE ((Employee.CURRENT_TERMINATION_DATE) Is Null) AND (Employee.EMPLOYEE_NUMBER" & EmployeeNumberText & ") " & _ "GROUP BY Employee.EMPLOYEE_NUMBER " & _ ",IIF(Measurement_Period_History.PERIOD_YEAR <> " & DatePickerYear & " - 1, NULL, Measurement_Period_History.PERIOD_YEAR) " & _ ",IIF(Measurement_Period_History.PERIOD_YEAR <> " & DatePickerYear & " - 1, IIF(Employee.VARIABLE_EMPLOYEE = No, 2, 0), " & _ "IIF(Employee.VARIABLE_EMPLOYEE = No, 2, IIF(Measurement_Period_History.PERIOD_END < Emplo

stackoverrun.com

Запуск запроса параметра в Access VBA

Я пытаюсь запустить следующий запрос в функции VBA. Я продолжаю получать «Слишком мало параметров. Ожидаемый 1.»

strSQL = "Parameters [Report Date] DateTime;" & vbCrLf & _ "SELECT SCF.code AS [Stock Code], " & vbCrLf & _ "SCF.desc AS [Description], " & vbCrLf & _ "SCF.grp AS [Product Group]," & vbCrLf & _ "SCF.qCurr AS [Closing Stock], " & vbCrLf & _ "SCF.abp AS [Avg Price], " & vbCrLf & _ "Sum(([Closing Stock]*[Avg Price])) AS [STOCK VALUE], " & vbCrLf & _ "MaxDate.tDate AS [Last Transaction Date], " & vbCrLf & _ "Sum(IIf(([Last Transaction Date]>[Report Date]),([Closing Stock]*[Avg Price]),0)) AS [After Report Date], " & vbCrLf & _ "DateDiff(""d"",[Last Transaction Date],[Report Date]) AS [Days since Last Transaction], " & vbCrLf & _ "[Report Date]" & vbCrLf & _ "INTO [FinReport] " & vbCrLf & _ "FROM SCF RIGHT JOIN MaxDate ON MaxDate.parent = SCF.this " strSQL = strSQL & _ "WHERE (SCF.qCurr 0) " & vbCrLf & _ "GROUP BY SCF.code, " & vbCrLf & _ "SCF.desc, " & vbCrLf & _ "SCF.grp, " & vbCrLf & _ "SCF.qCurr, " & vbCrLf & _ "SCF.abp, " & vbCrLf & _ "MaxDate.tDate" & vbCrLf & _ "ORDER BY MaxDate.tDate;" Set qdf = db.CreateQueryDef("", strSQL) qdf.Parameters("[Report Date]").Value = Form_IO_Form.ReportDate_TB.Value qdf.Execute

Я проверил, что все поля (кроме, конечно, [Дата отчета]) существуют, и запрос выполняется сам по себе в качестве запроса доступа (всплывающее окно запрашивает [Дата отчета]).

Помогите!

Редактировать 1: как запрошено здесь файл DB в виде ZIP. Это файл Access 2007. .accdb Файл DB

ru.1answer.info

vba - Microsoft Access VBA для редактирования SQL-запросов

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

Вопрос, похоже, предполагает, что запросы в Access должны быть сохранены. Они этого не делают. Вы можете выполнить любую произвольную строку SQL в любое время, либо в коде, либо (для не-DML SQL) в качестве источника записи формы или отчета. Строки SQL могут быть созданы "на лету" и назначены по мере необходимости во время выполнения - единственное преимущество сохраненного QueryDef заключается в том, что вам нужно использовать его в нескольких местах.

Сохраненный QueryDef в основном такой же, как VIEW в серверных базах данных.

Если у параметра QueryDef есть параметры, он эквивалентен простой ХРАНЕНИИ ПРОЦЕДУРА (т.е. те, у которых отсутствует код, например, разветвление IF/THEN или CASE SELECT).

Если вы реализуете SQL как VIEW в базе данных сервера, сохраните его как QueryDef in Access. Если вы сделаете это как SPROC в своей базе данных сервера, выполните его как запрос сохраненных параметров.

Но прежде всего определите, нужно ли вообще его сохранять.

Для чего это стоит, я профессионально программировал в Access с 1996 года, и, как правило, я не сохраняю много запросов и, в частности, не сохраняю критерии в запросах. Критерии специфичны для контекста среды выполнения и должны предоставляться во время выполнения, а не сохраняться в QueryDef. Я использую сохраненные QueryDefs для сложного SQL, которые мне нужно повторно использовать, или для определения "представлений" (особенно тех, которые имеют сложные соединения), которые используются более чем в одном месте приложения.

Исходный вопрос не определяет контекст, в котором требуется изменение критериев, поэтому на самом деле невозможно предложить лучший подход. Это случай, когда я бы поставил под вопрос вопрос об исключении правильного обсуждения, поскольку он предлагает конкретное РЕШЕНИЕ и спрашивает, как его реализовать, вместо того, чтобы описывать ПРОБЛЕМУ и запрашивать диапазон работоспособных решений. Чтобы сделать последнее, нам нужно знать об этом контексте (это SQL DML или SELECT? Используется ли он в коде или в качестве источника записей для формы или отчета? И т.д.), Но это полностью отсутствует здесь, поэтому полный спектр решений никогда не будет предлагаться.

qaru.site

access-vba - Как выполнить запрос append в ms-доступе vba как часть транзакции

Я очень новичок в программировании и создаю базу данных инвентаризации моей компании на MS Access 2016. До сих пор мне удалось получить доступ к макросам, но я пытаюсь выполнить транзакцию, выполненную из приложений append и delete и я борюсь с кодом vba.

Я понял, как выполнить транзакцию, в которой запросы выходят из строя при ошибке. Тем не менее, запрос append, который я пытаюсь включить в транзакцию, это рисовать значения из пустой формы, и, насколько я могу судить, это означает, что мне нужно определить параметры запроса в коде.

Таким образом, это код, в котором работают транзакции и обработка ошибок:

Private Sub Command0_Click() Dim ws As DAO.Workspace, db As DAO.Database Set ws = DBEngine.Workspaces(0) Set db = ws.Databases(0) Set qdf = db.QueryDefs On Error GoTo ErrTrap ws.BeginTrans DoCmd.SetWarnings False db.Execute "TESTQRY1", dbFailOnError db.Execute "TEST2QRY", dbFailOnError db.Execute "TESTQRY3", dbFailOnError ws.CommitTrans MsgBox ("You have successfully updated the data") DoCmd.SetWarnings True Exit Sub ErrTrap: ws.Rollback MsgBox "Rollback needed because:" & vbCr & Err.Description End Sub

И это код, который работает для фактического запуска запроса, но который не имеет обработки ошибок или транзакций:

Private Sub Add_Click() Dim db As DAO.Database Dim qry As DAO.QueryDef Dim ws As DAO.Workspace Set ws = DBEngine.Workspaces(0) Set db = ws.Databases(0) Set qry = db.QueryDefs("APPENDQRY") qry.Parameters(0) = Forms!LotNumberFrm!txtLotNumber qry.Parameters(1) = Forms!LotNumberFrm!txtFWNumber qry.Parameters(2) = Forms!LotNumberFrm!txtExpDate qry.Parameters(3) = Forms!LotNumberFrm!chkActive qry.Execute Exit Sub End Sub

Поэтому в основном моя проблема заключается в том, что мне нужно делать обе эти вещи одновременно - запустите запрос как часть транзакции с обработкой ошибок и определите параметры запроса в коде.

Я попытался нарезать и объединить эти два бита кода вместе несколькими путями без успеха. Любая помощь приветствуется.

qaru.site