2014-01-26 1 views
0

У меня есть таблица со следующими полями:Используйте цикл, чтобы выбрать несколько записей из таблицы для заполнения несвязанных текстовых полей в MS Access

StudentID 
ClassID 
TestID 
TestScore 

Для каждой уникальной комбинации ученика и класса, может быть до до 10 идентификаторов тестов и соответствующих тестов. У меня есть форма с 10 несвязанными текстовыми полями, которые соответствуют тестовым оценкам для 10 идентификаторов тестов. Я пытаюсь использовать форму для EDIT и ADD данных для моей таблицы (StudentScores). Поскольку его ученик может пропустить класс, каждая комбинация студенческого класса может не иметь 10 записей в таблице.

Я хотел бы иметь возможность использовать цикл в процедуре события для извлечения тестовых оценок из таблицы на основе выбранного студента и идентификатора класса для ввода в текстовые поля. Текстовые поля называются textbox1 через textbox10, соответствующие 10 TestID.

через поиск на форумах, как это, я был в состоянии придумать следующий код для извлечения данных из 10 несвязанных текстовых полей, чтобы добавить новые записи в таблицу:

Dim i As Integer 
Dim rst As DAO.Recordset 
Set rst = CurrentDb.OpenRecordset("StudentScores", dbOpenTable) 
For i = 1 To 10 
rst.AddNew 
rst![StudentID] = Me.StudentCombo1 
rst![ClassID] = Me.ClassCombo1 
rst![TestID] = i 
If Not IsNull(Controls("Textbox" & i)) Then 
    rst![TestScore] = CLng(Controls("Textbox" & i)) 
End If 
rst.Update 
Next 

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

Dim rst As DAO.Recordset 
mmySQL = "SELECT * from StudentScores where ClassID =" & Me.ClassCombo1 & "AND StudentID =" & Me.StudentCombo1 
Set rst = CurrentDb.OpenRecordset(mmySQL) 
rst.MoveFirst 
Do Until rst.EOF 
    Controls("Textbox" & rst![TestID]) = rst![TestScore] 
    rst.MoveNext 
Loop 
rst.Close 
Set rst = Nothing 
+1

Избавьтесь от пробелов в именах полей, вы поблагодарете себя позже. Посмотрите на мастер запросов кросс-таблицы. Вернитесь туда, где вы застряли. – Fionnuala

+0

Хорошо, я отредактировал мой вопрос. Надеюсь, это добавит ясности. – user3203169

+0

Являются ли ClassID и StudentID как числовыми, либо имеют тип данных Text? –

ответ

0

Перед тем, как к мясу вопроса, несколько замечаний:

  1. В настоящее время вы позволяете Null тестов в таблице StudentScores. У меня возникнет соблазн запретить их (т. Е. Установить обязательное свойство поля True), хотя вы знаете свои данные. Тем не менее, приведенный ниже код предполагает, что nulls не допускаются.

  2. Даже в небольших формах я бы избегал использования имен управления по умолчанию, таких как TextBox1. Общее соглашение о доступе заключается в использовании трехбуквенного префикса (например, txtTestScore1). Кроме того, почему ClassCombo1 и StudentCombo1, если есть только один из них? Однако я буду придерживаться вашего нынешнего названия для ясности.

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

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

  5. Если вы еще этого не сделали, вы можете поместить правило проверки в поле TestID для обеспечения значения от 1 до 10.

Итак, первая пара постоянных - объявить их в верхней части модуля формы:

Const MaxTextScoreCount = 10 
Const TestScoreTextBoxPrefix = "TextBox" 

Далее способ, чтобы очистить существующие значения на форме:

Sub ClearTestScoreTextBoxes() 
    Dim I As Integer 
    For I = 1 To MaxTextScoreCount 
    Me.Controls(TestScoreTextBoxPrefix & I).Value = Null 
    Next I 
End Sub 

В-третьих, вспомогательная функция для создания предложения WHERE из списков со списком:

В-четвертых, метод для заполнения текстовых полей с выбором:

Sub UpdateTestScoreTextBoxes() 
    Dim RS AS DAO.Recordset, SQL As String 
    SQL = "SELECT TestID, TestScore FROM StudentScores" + BuildWhereClause 
    Set RS = CurrentDb.OpenRecordset(SQL, dbForwardOnly) 
    ClearTestScoreTextBoxes 
    While Not RS.EOF 
    Me.Controls(TestScoreTextBoxPrefix & RS!TestID).Value = RS!TestScore 
    RS.MoveNext 
    Wend 
End Sub 

В-пятых, метод обновления базы данных из текстовых полей:

Sub UpdateDatabase() 
    Dim DB AS DAO.Database, I As Integer, Score As Variant, WhereClause as String, SQL As String 
    Set DB = CurrentDb 
    For I = 1 To MaxTextScoreCount 
    Score = Me.Controls(TestScoreTextBoxPrefix & I).Value 
    WhereClause = BuildWhereClause + " AND TestID = " & I 
    If IsNull(Score) Then 
     SQL = "DELETE FROM StudentScores" + WhereClause 
    ElseIf DB.OpenRecordset("SELECT 1 FROM StudentScores" + WhereClause).EOF Then 
     SQL = "INSERT INTO StudentScores(StudentID, ClassID, TestID, TestScore) " + _ 
      "VALUES (" & StudentCombo1.Value & "," & ClassCombo1.Value & "," & _ 
      I & "," & Score & ")" 
    Else 
     SQL = "UPDATE StudentScores SET TestScore = " & Score & WhereClause 
    End If 
    DB.Execute SQL 
    Next I 
End Sub 

Если это сделать ...

+0

Крис, большое спасибо за ваш ответ. Мне удалось изменить какой-то другой код, который я нашел, и смог двигаться дальше. Тем не менее, ваше решение кажется очень элегантным, и я намерен попробовать его, когда у меня будет больше времени. Еще раз спасибо. – user3203169

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