В VB.Net , как повторно заполнить сетку данных с нуля?

#vb.net #datatable #datagrid #sqlcommand #dataadapter

#vb.net #datatable #datagrid #sqlcommand #dataadapter

Вопрос:

Я написал общий VB.net подпрограмма, которая заполняет сетку данных результатами запроса. Подпрограмма в качестве одного параметра, strQuery, которая представляет собой строку, которая может преобразовываться в любое допустимое представление SQL-сервера или хранимую процедуру, которая возвращает набор записей. Кроме этого, нет никаких ограничений на код SQL, и отправка двух запросов с совершенно разными профилями полей является допустимым предложением.

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

Я, наконец, решил проблему. Возможно, мне следовало упомянуть, что я использую Visual Studio 2010, и что если Херси использовал более позднюю версию, то код, который работал для него, возможно, не работал для меня. Изменение в моем коде — это одна дополнительная строка: присвоение имени и datapropertyname одного и того же имени. Я заметил, что, когда я перешел к просмотру представления столбца, я заметил, что datapropertyname — это то, как таблица ссылается на источник, а имя является эффективным псевдонимом для поля, как оно будет представлено. Очевидно, что для ясности оба должны быть одинаковыми! Теперь это работает так, как рекламируется. Спасибо, ~ Питер Фербер

 Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    Dim con As New SqlConnection("<Enter Connection string here>")
    Dim rcd As ADODB.Recordset = ReturnRecordset("Select * From ExcludeWords")
    Call DefineDataGrid("Select * From ExcludeWords")
End Sub

Private Sub btnUpdate_Click(sender As System.Object, e As System.EventArgs) Handles btnUpdate.Click
    Call DefineDataGrid("Select * From FindWords")
End Sub

Sub DefineDataGrid(ByVal strQuery As String)
    Dim con As New SqlConnection("<Enter Connection String Here>")
    Dim dt As New DataTable

    FindWordGrid.Columns.Clear()
    FindWordGrid.DataSource = Nothing

    Dim rcd As ADODB.Recordset = ReturnRecordset(strQuery)

    Dim MyField As ADODB.Field

    Dim iCount As Integer = -1
    FindWordGrid.ColumnCount = rcd.Fields.Count
    For Each MyField In rcd.Fields
        iCount = iCount   1
        FindWordGrid.Columns(iCount).Name = MyField.Name
        FindWordGrid.Columns(iCount).DataPropertyName = MyField.Name
    Next

    Dim cmd As New SqlCommand(strQuery, con)
    Dim da = New SqlDataAdapter(cmd)
    da.Fill(dt)
    FindWordGrid.DataSource = dt
End Sub

Function ReturnRecordset(strQuery As String) As ADODB.Recordset
    Dim con As ADODB.Connection = "<Enter Connection string here>"

    ReturnRecordset = New ADODB.Recordset
    ReturnRecordset.Open(strQuery, con)
End Function
  

Мою настройку легко воспроизвести: я использую наборы данных, содержащие всего несколько записей в каждой соответствующей таблице. Единственным ограничением является то, что соответствующие прогоны должны иметь другой профиль поля. Я экспериментировал с различными методами большую часть дня, и теперь я думаю, что лучше всего получить немного нового серого материала по этому вопросу. Правильное выполнение этого процесса — последнее серьезное препятствие для меня в создании ключевой презентации, которую я хочу сделать, в лоббировании должности. Заранее спасибо за ваши комментарии, мысли и идеи.
С уважением, ~ Питер Фербер

Комментарии:

1. Во-первых, ваш код не будет работать с «любым допустимым представлением SQL-сервера или хранимой процедурой». Это будет работать только с фактическим SELECT оператором, потому что вы принимаете значение по умолчанию CommandType Text .

2. Если после привязки нет строк, то в источнике данных нет строк. Вы можете проверить, сколько записей было извлечено, посмотрев на число, возвращенное Fill методом.

3. Спасибо всем за ваши ответы. В попытке очистить коллекцию столбцов я добавил следующую строку:

4. Если ваши запросы могут не выдавать результирующие наборы с той же схемой, вам необходимо очистить существующие столбцы из сетки. Для этого установите значение DataSource to Nothing , Clear Columns collection, а затем установите DataSource снова. Это автоматически сгенерирует новые столбцы.

5. Спасибо всем за ваши ответы. В попытке очистить коллекцию столбцов я изменил блок кода в исходном вопросе, чтобы показать мою обновленную попытку следовать инструкциям jmcihinney. Когда я это делаю, либо выше, либо ниже строки, устанавливающей источник данных в nothing, я получаю пустую сетку данных при первом проходе. При написании «FindWordGrid. Столбцы. Clear ()», что-то, похоже, полностью демонтирует функциональность сетки данных. Я делаю что-то не так? С уважением, могу ли я предложить воспроизвести простую настройку, которую я описал, и протестировать ваши исправления? Спасибо. ~ Peter Ferber

Ответ №1:

Итак, внес пару изменений в опубликованный вами код DefineDataGrid. Кажется, это работает для меня. Я подозреваю, что это может быть как-то связано с жизненным циклом ваших объектов cmd или con, вызывающих вашу проблему. Разбор нескольких разных запросов к нему, и он правильно перестраивает datagridview

 Sub DefineDataGrid(ByVal strQuery As String)
    Dim dt As New DataTable
    FindWordGrid.DataSource = Nothing
    Using con As New SqlConnection("Your Connection String Here")
        Using cmd As New SqlCommand(strQuery, con)
            Dim da = New SqlDataAdapter(cmd)
            da.Fill(dt)
            FindWordGrid.DataSource = dt
        End Using
    End Using
End Sub
  

Изменил очевидные реализации con и cmd на уровне модуля на локальные переменные, и поскольку оба типа реализуют IDisposable, обернул их в шаблон Using

Комментарии:

1. Это потрясающе, Херси. Спасибо за должную осмотрительность в этом вопросе. Я получаю сообщение об ошибке во второй раз, когда сталкиваюсь со строкой «da.Fill (dt)», и я получаю сообщение об ошибке «Свойство connectionstring не инициализировано». Это нормально, и мне кажется, что ваша оценка жизненного цикла — правильный путь. Я буду продолжать нудеть. То, что вы добились успеха с вашей стороны, говорит мне о том, что решение уже близко. Большое спасибо!

2. @user3621522, в опубликованном коде явно указано «Ваша строка подключения здесь» , поэтому, если ваше ConnectionString свойство не задано, вы проигнорировали эту часть.

3. Опубликованный код пренебрегает очисткой столбцов сетки после очистки DataSource , что означает, что столбцы из предыдущих запросов останутся.

4. Это потрясающе, Херси. Спасибо за должную осмотрительность в этом вопросе. Я получал сообщение об ошибке во второй раз, когда сталкивался со строкой «da.Fill (dt)», в которой говорилось: «Свойство connectionstring не инициализировано». Итак, я изменил созданное новое соединение внутри подпрограммы, и это предотвращает возникновение ошибки, но старая конфигурация поля все еще действует во время второго запуска. Я уверен, что я на правильном пути, так как у вас есть проверенный показатель успеха при использовании этого метода. Хорошая работа, и спасибо!

5. @user3621522, может быть, обновите свой вопрос своей последней попыткой и укажите, как вы создаете свое соединение