2012-07-05 3 views
3

У меня возникли некоторые проблемы с некоторыми функциями моего приложения. Существует конкретный экземпляр, в котором у меня есть экземпляр «ожидающего класса» в форме для проверки администратором. Форма заполняется учащимися, связанными с этим ожидающим классом. После того, как их оценки закончены, у меня есть кнопка в нижнем колонтитуле, которая удалит этот класс из моей «ожидающей» таблицы и добавит оценки всем ученикам. Это работает. Однако я хочу по существу копировать этот ожидающий класс, который просто имеет имя класса, дату и учитель до завершенной таблицы классов, прежде чем он будет удален из ожидающего. Поскольку в этой форме не сохраняется никаких данных об этом классе, отличном от первичного ключа (номер класса), я не могу заполнить другие поля (имя класса, дата) строки в моей заполненной таблице классов.MS access SELECT INTO in vba

Я пытаюсь выполнить операцию «SELECT INTO» в VBA, чтобы получить эти значения. Это происходит так:

dim cname as String 
    dim classdate as Date 
    dim pid as integer 
    dim teacher as String 
    dim qry as String 

    pid = [Forms]![frmClasses]![txtID] 

    qry = "Select className INTO cname FROM tblPending WHERE tblPending.id = " & " ' " & pid & " ' " & ";" 

    db.execute qry 
    debug.print qry 
    debug.print cname 

Отсюда, я делаю те же операции для каждой другой переменной, построить мой ВСТАВИТЬ запрос и выполнить его. Проблема в том, что мой выбор не работает. Debug.print показывает, что локальные переменные никогда не инициализировались из инструкции SELECT INTO. Есть предположения?

+0

Это запрос таблицы make, я считаю, что вы хотите добавить запрос. Я действительно не думаю, что ваш идентификатор - это текст. Если pid равно null (пустое), то кажется вероятным, что [Forms]! [FrmClasses]! [TxtID] пуст. Попробуйте использовать ключевое слово Me и посмотрите, какие контрольные имена он вызывает - Me. будет воспитывать intellisense. – Fionnuala

+0

Я не могу использовать ключевое слово Me в этом случае. Вместо того, чтобы открывать форму с параметром, я использую поле из предыдущей формы. Поле с txtID (текстовое поле с идентификатором соответствующего класса) находится в предыдущей форме. Кроме того, эта часть работает по назначению. Выведенный запрос: «Выберите ClassName INTO cName FROM tblPending WHERe tblPending.id = '17';" Я также попытался удалить одиночные кавычки вокруг критериев id, так как это целое число, но это не имеет значения. – Scotch

+0

В зависимости от того, какой выбор я сделал из предыдущей формы, я получаю правильный соответствующий класс ID – Scotch

ответ

2

Во-первых, наличие всех классов в одной таблице и просто установка столбца «NotPending» или «Completed» будет лучше.
Наличие двух идентичных таблиц для классов и перемещение значений из одного в другое для указания изменений состояния - это плохой дизайн базы данных.


Если вы действительно нужно сделать это с помощью двух таблиц и копирование строк, то вам нужно an INSERT INTO querynot SELECT INTO), как уже упомянуто Remou в комментариях, потому что SELECT INTO создает новую таблицу (или перезаписывает существующий с тем же именем, если он уже существует).

Синтаксис INSERT INTO выглядит следующим образом:

INSERT INTO CompletedClassTable (ClassName, Teacher) 
SELECT ClassName, Teacher FROM tblPending WHERE id = 123 

И, наконец, вы спрашивали об этом в комментарии:

Так SELECT INTO полностью отличается в доступе, чем Oracle? В Oracle и PL/SQL вы можете выбрать строку в переменной ИЛИ таблице. В Access вы не можете выбрать переменную?

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

Пример код для загрузки вашего запроса в Recordset и вывод ClassName поля:

Dim RS As DAO.Recordset 

Set RS = CurrentDb.OpenRecordset("SELECT * FROM tblPending WHERE id = 123") 
If Not RS.EOF Then 
    Debug.Print RS("classname") 
End If 
RS.Close 
Set RS = Nothing 
+0

. Я чувствую, что мое намеренное использование для «выбора в» неправильно понимается. Мое намерение состояло в том, чтобы ВЫБРАТЬ INTO, чтобы получить значение из строки и присвоения ее переменной в VBA из таблицы, где я знаю ПК, как и в PL/SQL. Исключение через RS, по-видимому, является сравнительным решением для Access, как вы упомянули. Что касается дизайна базы данных, ожидающая таблица и заполненная таблица не являются ТОЧНЫМИ. В моей заполненной таблице есть все поля ожидающей таблицы с добавлением нескольких полей.В этом случае я просматриваю завершенный класс и класс, который выполняется (в ожидании), как разные объекты. – Scotch

+0

Я не уверен, был ли мой вопрос неоднозначным или мои намерения были неясны, но я пойду и отметю это как «ответил '- НЕВОЗМОЖНО использовать «SELECT INTO» в VBA, чтобы назначить значение из строки переменной. Для этого мне нужно будет открыть набор записей необходимого запроса. По вашему мнению, это подходящее резюме? – Scotch

+1

Я не знаю Oracle и PL/SQL, поэтому я не могу сказать, как это работает там, кроме того, что вы сказали. Чтобы назначить значение из строки переменной, вам понадобится «Recordset» или, если вам нужно только одно значение, [вы можете использовать «DLookup»] (http://office.microsoft.com/en-us/access -help/DLookup-функция-HA001228825.aspx). Но если вы просто хотите скопировать строку в другую таблицу, я бы использовал запрос INSERT INTO. ИМО это самый простой способ сделать это. –

1

Кажется, что вы хотите получить текстовое значение, className, от tblPending где tblPending.id соответствует найденному значению в текстовом поле, txtID, и сохраните это текстовое значение в строковой переменной с именем cname.

Если эта интерпретация верна, вам не нужно беспокоиться о запросе и наборе записей. Просто используйте DLookup Function для получения значения, похожего на этот образец непроверенного кода.

Dim cname As String 
Dim pid As Integer 
Dim strCriteria As String 
pid = [Forms]![frmClasses]![txtID] 
strCriteria = "id = " & pid 
cname = Nz(DLookup("className", "tblPending", strCriteria), vbNullString) 
Debug.Print "cname: '" & cname & "'" 

Примечание:

  1. Я предположил тип данных id поля в tblPending является числовым. Если это на самом деле тип данных текст, изменить strCriteria так:

    strCriteria = "ID = '& PID & "'"

  2. DLookup() возвращает Null, если совпадений не найдено. Поскольку мы присваиваем возвращаемое значение функции строковой переменной, я использовал Nz() для преобразования Null в пустую строку. Кроме того, вы можете объявить cname как Variant (чтобы он мог принять значение Null) и избавиться от Nz().

+0

Это тоже работает. Я внедрил свою форму с помощью dLookup после того, как вы отправили свой комментарий на мой вопрос^и он работает (мой код похож на код, который вы предоставили с этим ответом). Раньше я использовал скрытый контроль над предыдущей формой для хранения переменных - уродливое обходное решение, так как я не знал о DLookup(). Спасибо, что сообщили мне об этом, я уверен, что буду использовать его часто в будущем, так как мне более удобно кодировать мои вставки, обновления и удаления в VBA, а не использовать операции по умолчанию, предоставляемые мастерами. – Scotch

+1

Как только я понял, что вы действительно хотели ВЫБРАТЬ В * переменную *, 'DLookup()' возникло как простое решение. Когда я впервые прочитал ваш вопрос, я неверно истолковал цель как сохранение значения SELECT в таблице (новой или существующей). – HansUp

+0

Я думаю, что это и думали Remou и Christian. Я использую SELECT INTO для получения значений из таблицы в локальную переменную в PL/SQL. Отсюда и возникла путаница. Я не хотел «SELECT INTO», я хотел знать, что такое эквивалент Access этой операции. DLookup - это тот ответ, который был нужен. – Scotch

Смежные вопросы