Как получить данные из SQL-запроса в Microsoft Access VBA? - PullRequest
7 голосов
/ 12 июля 2009

Эй, я только что узнал, как поместить свои операторы SQL в VBA (или, по крайней мере, записать их), но я понятия не имею, как вернуть данные?

У меня есть пара форм (диаграмм), основанных на запросах, с которыми я запускаю довольно регулярные параметры, просто меняя сроки (например, топ-10 продаж за месяц). Затем у меня есть процедуры, которые автоматически переносят объект диаграммы в презентацию PowerPoint. Итак, у меня есть все эти запросы, предварительно построенные (например, 63), и формы диаграмм для соответствия (э-э, да .... 63 ... я знаю, что это плохо), а затем все эти вещи настроены на "open / «закрыть» события, вызывающие следующее (это как моя самая лучшая попытка быть взломщиком… или домино; в зависимости от того, что вы предпочитаете).

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

Итак, кроме вопроса, который я задал вверху, кто-нибудь может дать совет? спасибо

Ответы [ 6 ]

9 голосов
/ 12 июля 2009

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

Dim dbs As Database
Dim rs As Recordset
Dim strSQL As String
Set dbs = CurrentDb

strSQL = 'your query here

Set rs = dbs.OpenRecordset(strSQL)

If Not (rs.EOF And rs.BOF) Then
  rs.MoveFirst
  'get results using rs.Fields()
Else

'Use results

За комментарий: взгляните на класс записей . Он содержит коллекцию Fields, которая является столбцами, возвращаемыми по вашему запросу. Трудно сказать, не зная вашей схемы, но что-то вроде ...

rs.MoveFirst
Do While Not rs.EOF
   'do something like rs("SomeFieldName") 
   rs.MoveNext
Loop

Как я уже сказал, вам лучше всего взять книгу на эту тему, у них множество примеров.

3 голосов
/ 12 июля 2009

Используйте параметризованный querydef и вызывайте его из vba.
Запрос проще в разработке ... легко тестируется ... и легко доступен из VBA или формы.

dim qd as querydef
set qd = currentdb.querydefs!myquerydef

qd.parameters!parm1=val1

....

либо qd.execute

или

dim rs as recordset
set rs = qd.openrecordset()

YMMV ...

2 голосов
/ 12 июля 2009

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

Итак, используйте CONST или создайте строку для своего оператора SQL и вставьте в качестве аргумента строку SANITIZED, NON SQL INJECTED:)

т.е.

strSQL = "SELECT * FROM Customer WHERE ID = " & EnsureParamIsNotSQLInjection(customerID)

... затем вызывайте функцию / sub из любого места, где вам нужно получить набор записей / данных / выполнить оператор. Подумайте о создании нескольких функций / подпрограмм для доступа к данным, в которых вы можете просто выполнить инструкцию UPDATE, или получить одно значение, или получить полный набор записей.

Ключевым моментом здесь является то, чтобы все эти функции жили в одном месте и повторно использовали их повсюду. Вот пример в VBScript .

Sub DoStuff(strSQL)

   Set adoCon = Server.CreateObject("ADODB.Connection")


    strConnString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Server.MapPath("db\Database.mdb") 
    'strConnString = "DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=" & Server.MapPath("db\Database.mdb")

   adoCon.Open strConnString

   Set rsMain = Server.CreateObject("ADODB.Recordset")

   rsMain.Open strSQL, adoCon

   Do While NOT rsMain.EOF
      customerName = rsMain("CustomerName") 'silly example
      RsMain.MoveNext
   Loop

   rsMain.Close

   Set adoCon = Nothing
End Sub
1 голос
/ 13 июля 2009

«если вы хотите разрешить пользователю выбирать N в операторе TOP N SQL» - ну, вы можете использовать коррелированный подзапрос (вместо динамического SQL), например, (Синтаксис режима запросов ANSI-92):

CREATE PROCEDURE GetOrdersTopN
(
 :N INTEGER
)
AS 
SELECT O1.OrderDate, O1.CustomerID
  FROM Orders AS O1
 WHERE :N >= (SELECT COUNT(*) + 1
               FROM Orders AS O2
              WHERE O1.OrderDate < O2.OrderDate);

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

1 голос
/ 13 июля 2009

Еще один способ сделать это, который, кажется, никто не упомянул, - это привязать ваш график к одному сохраненному QueryDef, а затем во время выполнения переписать QueryDef. Теперь я не рекомендую изменять сохраненные QueryDef для большинства контекстов, потому что это вызывает раздувание внешнего интерфейса и обычно даже не требуется (большинство контекстов, где вы используете сохраненный QueryDef, могут быть отфильтрованы тем или иным способом в контексте, в котором они используются, например, как источник записей формы, вы просто передаете один аргумент в DoCmd.OpenForm).

Графики отличаются, потому что SQL, управляющий графиками, не может быть изменен во время выполнения.

Некоторые предложили параметры, но при открытии формы с графиком, использующей строку SQL с параметрами, появятся диалоговые окна параметров по умолчанию. Один из способов избежать этого - использовать диалоговую форму для сбора критериев, а затем установить ссылки на элементы управления в диалоговой форме в качестве параметров, например ::

.
PARAMETERS [Forms]![MyForm]![ID] Long;

Если вы используете ссылки на формы, крайне важно, чтобы вы это делали, потому что начиная с Access 2002, служба Jet Expression не всегда правильно обрабатывает их, когда элементы управления имеют значение Null. Определение их в качестве параметров устраняет эту проблему (которой не было до Access XP).

Одна ситуация, в которой вы должны переписать QueryDef для графа, это если вы хотите позволить пользователю выбирать N в операторе TOP N SQL. Другими словами, если вы хотите, чтобы они могли выбирать TOP 5, TOP 10 или TOP 20, вам придется изменить сохраненный QueryDef, поскольку N не может быть параметризован.

1 голос
/ 12 июля 2009

Несмотря на запутанность, ваш путь проще, чем попытка построить операторы SQL в VBA. Помните, что сохранение запросов по отдельности позволяет вам манипулировать ими визуально. Также есть некоторые преимущества в производительности.

Лучшее понимание SQL поможет вам консолидировать и упростить существующие запросы (если их даже нужно упростить. Похоже, что они выполняют большую работу, поэтому вам, возможно, понадобится все 64 запроса).

Тем не менее, довольно просто выполнять SQL-запросы в коде:

Dim strSQL as String
strSQL = "UPDATE Table MyTable SET fieldname = 1 WHERE fieldname = 0;"
DoCmd.RunSQL strSQL
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...