質問者
DataGridViewについて

質問
-
開発環境
Visual Studio 2013(Basic)windows 10 pro 64bit.NET Framework 4.5SQLはSQLiteを使用しています。
2番目の項目を削除すると
となり、1番目の項目が空白になりまして、、、、
Dim deletePath As String = Nothing
' ------------------------------------------------------
' エラーチェック
' ------------------------------------------------------
If name = Nothing Then
'メッセージボックスを表示する
MessageBox.Show("削除する項目を選択してください", _
"エラー", _
MessageBoxButtons.OK, _
MessageBoxIcon.Error)
Exit Sub
End If
' ------------------------------------------------------
' SQL 削除処理
' ------------------------------------------------------
Dim dt As DataTable = New DataTable()
'SQLiteへの接続情報の設定をします。
Dim builder As SQLiteConnectionStringBuilder = New SQLiteConnectionStringBuilder()
'SQLiteのファイルへのパスを設定します。
builder.DataSource = ".\recipe.db"
'接続情報を使ってコネクションを生成します。
Using conn As New SQLiteConnection(builder.ConnectionString)
'オープン
conn.Open()
'SQL文とコネクションを設定します。
Using cmd As New SQLiteCommand("SELECT dir FROM exrecipe where name = @name", conn)
'パラメータの作成
Dim prmtr1 As SQLiteParameter = New SQLiteParameter()
'パラメータ名は@を除いた名前を指定します。
prmtr1.ParameterName = "name"
'パラメータの値を設定します。
prmtr1.Value = name
'パラメータをコマンドに追加します。
cmd.Parameters.Add(prmtr1)
'SQLiteへの橋渡しのアダプターを設定します。
Dim sda As SQLiteDataAdapter = New SQLiteDataAdapter()
'SELECTコマンドを設定します。
sda.SelectCommand = cmd
'SELECTの実行及びフェッチ
sda.Fill(dt)
deletePath = dt.Rows(0)(0).ToString()
sda.Dispose()
End Using
'SQL文とコネクションを設定します。
Using cmd As New SQLiteCommand("delete from exrecipe where name = @name", conn)
'パラメータの作成
Dim prmtr1 As SQLiteParameter = New SQLiteParameter()
'パラメータ名は@を除いた名前を指定します。
prmtr1.ParameterName = "name"
'パラメータの値を設定します。
prmtr1.Value = name
'パラメータをコマンドに追加します。
cmd.Parameters.Add(prmtr1)
'データ更新
cmd.ExecuteNonQuery()
End Using
'DataGridView1で選択されているすべての行を削除する
Dim r As DataGridViewRow
For Each r In DataGridView1.SelectedRows
If Not r.IsNewRow Then
DataGridView1.Rows.Remove(r)
End If
Next r
'SQL文とコネクションを設定します。
Using cmd As New SQLiteCommand("SELECT name,genre,DateTime FROM exrecipe WHERE @DateTime", conn)
Dim prmtr As New SQLiteParameter("@DateTime", GetDate.ToString("yyyy年MM月dd日"))
'パラメータをコマンドに追加します。
cmd.Parameters.Add(prmtr)
'SQLiteへの橋渡しのアダプターを設定します。
Dim sda As SQLiteDataAdapter = New SQLiteDataAdapter()
'SELECTコマンドを設定します。
sda.SelectCommand = cmd
'SELECTの実行及びフェッチ
sda.Fill(dt)
'グリッドに表示します。
DataGridView1.DataSource = dt
sda.Dispose()
End Using
End Using
' ------------------------------------------------------
' ファイルの 削除処理
' ------------------------------------------------------
Try
System.IO.File.Delete(deletePath)
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.OkOnly + MsgBoxStyle.Critical, "エラー")
End Try一番目の空白をなくす方法が分からない状態です。
ソースはSQLiteのexRecipeというテーブルから
なぜか、空白が出来てしまうので、良く分からない状態でいます。
1番目:選択した項目のDIRを取得するSQL文を実行
2番目:選択したSQL文の削除
DataGridViewの中身をクリアして
最後に今日の日付のSQL文を表示するプログラムです。
そして、DIRのPDFを削除しています
- 編集済み RappyKakuwane 2022年12月9日 5:06 プログラムの説明をいれました
すべての返信
-
何をしたいのか、何が質問なのか質問文から分かっていませんが・・・
DataGridView のある行を選択してから[レシピの削除]ボタンをクリックしたとき、その行を消したい(中身を空白にするだけでなく行ごと表示されないようにしたい)のだが、現状は質問の 2 つ目の画像にあるように中身が空白の行が残ってしまうということですか?
であれば、アプリの構造を以下のようにして、
SQLite ⇔ DataTable ⇔ BindingSource ⇔ DataGridView
[レシピの削除]ボタンクリックのイベントハンドラで BindingSource.RemoveCurrent() を実行すれば良いです。
以下の記事は、CSV ファイル ⇔ DataTable ⇔ BindingSource ⇔ DataGridView という構造で、button2_Click でそれを行っています。
CSV ファイルを DataGridView に表示
http://surferonwww.info/BlogEngine/post/2020/09/11/show-date-in-csv-file-on-datagridview.aspx
- 編集済み SurferOnWww 2022年12月9日 6:27 訂正
-
上のレスで「あとでサンプルを書いておきます。」と書いた件です。
以下の SQLite のテーブル Movie を使います。Id 列は主キーで AUTOINCREMENT です。
デザイン画面でツールボックスから DataGridView, BindingSource と TextBox を 2 つドラッグ&ドロップします。
コードは以下の通りです。C# が読めなければ変換サービスがありますので使ってみてください。
Telerik Code Converter
https://converter.telerik.com/
using System; using System.Data; using System.Data.SQLite; using System.Windows.Forms; namespace WindowsFormsSQLite { public partial class Form1 : Form { private SQLiteDataAdapter adapter; private DataTable table; public Form1() { InitializeComponent(); this.dataGridView1.DataSource = this.bindingSource1; } private void Form1_Load(object sender, EventArgs e) { var connString = @"Data Source=C:\Users...\Movie.db"; var selectQuery = "SELECT Id, Title, ReleaseDate, Genre, Price FROM Movie"; var connection = new SQLiteConnection(connString); var command = new SQLiteCommand(selectQuery, connection); this.adapter = new SQLiteDataAdapter(); this.adapter.SelectCommand = command; new SQLiteCommandBuilder(this.adapter); this.table = new DataTable(); this.adapter.Fill(table); this.bindingSource1.DataSource = this.table; } private void Update_Click(object sender, EventArgs e) { this.adapter.Update(this.table); } private void Remove_Click(object sender, EventArgs e) { this.bindingSource1.RemoveCurrent(); } } }
実行すると以下のようになり、行を選択を選択(▶ 印の行がそれ)して[RemoveItem]ボタンをクリックすれば上のコードの Remove_Click メソッドが動いて行が削除されます。
さらに[UpdateAll]ボタンをクリックすればその結果が SQLite に反映されます。コードの SQLiteCommandBuilder がそのあたりのキモです。是非それも勉強することをお勧めします。
- 編集済み SurferOnWww 2022年12月10日 8:30 訂正
-
new SQLiteCommandBuilder(this.adapter);
このあたりで構文えらーとなったので、試行錯誤して自分なりにソースを変えて動かしてみました。
動く段階まで出来たのですが、、、、
[UpdateAll]でエラーになって、いる状態です。
すみません。コードのどこが不味いのか分からない状態です。
Imports System
Imports System.Data
Imports System.Data.SQLite
Imports System.Windows.Forms
Public Class Form1
Dim sda As SQLiteDataAdapter = New SQLiteDataAdapter()
Dim table As DataTable = New DataTable()
Public Sub New()
InitializeComponent()
Me.DataGridView1.DataSource = Me.BindingSource1
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim builder As SQLiteConnectionStringBuilder = New SQLiteConnectionStringBuilder()
'SQLiteのファイルへのパスを設定します。
builder.DataSource = ".\test.db"
'接続情報を使ってコネクションを生成します。
Using conn As New SQLiteConnection(builder.ConnectionString)
'SQL文とコネクションを設定します。
Using cmd As New SQLiteCommand("SELECT * FROM Movie", conn)
sda = New SQLiteDataAdapter()
sda.SelectCommand = cmd
Me.table = New DataTable()
sda.Fill(table)
Me.BindingSource1.DataSource = Me.table
End Using
End Using
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
sda.Update(Me.table)
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Me.BindingSource1.RemoveCurrent()
End Sub
End Class
-
質問する際の基本のキですが、エラーメッセージをコピペしてください。エラーメッセージには非常に重要な情報が含まれていて、それだけ見れば原因と解決策が分かることも多いのですよ。
> new SQLiteCommandBuilder(this.adapter);
> このあたりで構文えらーとなったので、試行錯誤して自分なりにソースを変えて動かしてみました。
new SQLiteCommandBuilder(this.adapter); を削除した結果、
>[UpdateAll]でエラーになって、いる状態です。
になったのだと思いますが、それは当たり前です。
先のレスで「コードの SQLiteCommandBuilder がそのあたりのキモです」と書いたのですから、Microsoft のドキュメントを読むなどしてそこを勉強しましょう。
なぜダメなのかを説明しておきます。以下の記事の図1と図2を見てください。
DB 設計者のための明解 ADO.NET 第 1 回
https://learn.microsoft.com/ja-jp/previous-versions/cc482903(v=msdn.10)?redirectedfrom=MSDN
図2の DataSet / DataTable の左に BindingSource 経由で DataGridView があるというのが紹介したアプリの構造です。
ユーザーが DataGridView を編集すると、その結果は図1にあるように DataSet の中の TataTable に反映されます。
Update で編集された DataTable の内容を Update, Delete, Insert コマンドで一気に DB に書き戻すようになっています。
new SQLiteCommandBuilder(this.adapter); がないと Update, Delete, Insert を動かすコードが生成されないのです。 -
RappyKakuwaneさん、こんにちは。フォーラムオペレーターのKumoです。
MSDNフォーラムにご投稿くださいましてありがとうございます。
ご質問いただいた件ですが、その後いかがでしょうか。
より詳しい情報を追加いただければ、回答が付きやすくなります。
よろしくお願いいたします。MSDN/ TechNet Community Support Kumo ~参考になった投稿には「回答としてマーク」をご設定ください。なかった場合は「回答としてマークされていない」も設定できます。同じ問題で後から参照した方が、情報を見つけやすくなりますので、 ご協力くださいますようお願いいたします。また、MSDNサポートに賛辞や苦情がある場合は、MSDNFSF@microsoft.comまでお気軽にお問い合わせください。~
-
変換すると
ここで構文エラーとなっていて、直し方がどうしてもわからないです。
- 編集済み RappyKakuwane 2022年12月12日 3:53 間違えました