• ベストアンサー

VB.NETからAccessテーブルの文字列を操作する際・・

VB2005からAccessのmdbのテーブルのあるカラムより数バイトを切り出して別のカラムにコピーするだけの単純なプログラムなのですが、以下のように30バイトや34バイトで切り出しているにもかかわらず16バイトしか入ってきません。 cn.ConnectionString = "Provider= Microsoft.Jet.OLEDB.4.0;" _ & "Data Source = d:\csmain\cstool\egz0omen.mdb" cn.Open() com = cn.CreateCommand() com.CommandText = "select カラムA from T_テーブル" dread = com.ExecuteReader Do While (dread.Read()) com = New OleDb.OleDbCommand("update T_テーブル set カラムB = LeftB(カラムA, 30), " _ & " カラムC = LeftB(カラムA, 34) , " _   & " カラムE = LeftB(カラムA, 36) ") com.Connection = cn com.ExecuteNonQuery() Loop <実行結果> カラムA             123456789012345 カラムB~カラムE全て 12345678 試しにバイト数を10バイトずつ増やして、30→40、34→44、36→46にしても結果は同じでした。 宜しくお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

ADO.NETでは、旧ADOのような、「カラム別に編集して1レコードずつUpdateメソッドで簡単に更新」 といった処理は出来ません。少なくともDataReaderでは無理です。 (DataAdapter、DataSetを使えば似たようなことは出来ますが、あちらは  プログラムから単純に見たら、基本的に一括更新です) で、今回の形でやるなら、結局UpdateのSQL Commandを実行するしか ないと思いますが、そこで気になることが2つ。 1.SQLにLeftBなんて関数は存在しません。   割と多くの初心者が勘違いされるようなんですが、SQL文は、あくまで   「DBに渡す、DB用の命令を記述した、ただの文字列」です。   SQL文の中に、VB内で使用している変数名を直接書いたり、VBの関数を   直接書いたりしても、勝手に置き換えたりは してくれません。   LeftBに類似したSQL関数は、DBによっては存在しますが、Accessだと無理っぽいですね。   (後述の通り、VB2005にもLeftBは無いんですけどね) 2.SQL Update文に、WHERE句がありません。   ループして1レコードずつ更新するなら、あくまで1回ごとのUpdate文の中で、   更新対象のレコードを指定するWHERE句が必要です。 使用するSQL文は、各カラムがテキスト型だとすると、 "update T_テーブル set カラムB = '" & _ LeftB(カラムA, 30) & "', カラムC = '" & _ LeftB(カラムA, 34) & "'," カラムE = '" & _ LeftB(カラムA, 36) & "' WHERE (検索条件はご自分で設定してください)" みたいな感じかな? (数値型の場合は、シングルクオートの編集を外してください) なお、VB2005にLeftB関数は存在しませんので、自作する必要があります。 (やり方としては、Shift-JISにエンコードしてから切り出して、Unicodeに戻すんだけど…  これについては、検索すればどこかにあるんじゃないかな) 余談ですが、ADO.NETについて踏み込んで勉強したい場合は、参考URLあたりが 結構いいと思います。多少難解ですが。

参考URL:
http://www.atmarkit.co.jp/fdotnet/basics/adonet_index/index.html
ryozyryozy
質問者

お礼

連絡大変遅くなりました。 ご指摘のとおりUPDATE文がおかしく、ループごとに全件レコード更新していたため、最終レコードの文字列のバイト数で更新されておりました。 それとLEFTB関数も確かにうまくいかずLEFT関数なら正常にいきました。 どうもありがとうございました。

その他の回答 (1)

回答No.1

とりあえず質問のプログラムを見た感想ですが・・・ 「カラム」というと勘違いしそうなので、フィールドとレコードで話をさせてもらいます。 カラムAからカラムEというフィールドを持つ全レコードに対して行う操作なのなら・・・ そのSQLは1度で全てのレコードに対してupdateを行うので、Do...loop内で複数回実行しているのはおかしいような気がします。 あるフィールドに対して、各レコードをカラムAからカラムEと言うのなら・・・ SQL文がおかしいような気がします。

ryozyryozy
質問者

補足

ご回答ありがとうございます。 確かにご指摘のとおりSQL文がおかしいです。 中略していますが、1レコードずつ読み込む必要がありますので Do..Loopは必要ですが、UPDATEである必要は全くありませんでした。 カラムB=LeftB(カラムA,30)のような代入式でよいのですが、 試してみるとやはり、com.ExecuteNonQueryでSQL文でないためエラーが出ます。 代入式でよい場合はどのようにしたらよいかご存知でしょうか?

関連するQ&A

  • VB.NETのOleDbCommandにて文字列を操作する際、文字列にダブルクォーテーションが入っていた場合は?

    以下のようにmdbのT_テーブルにある「名称」というフィールドの文字列を操作するだけの単純なプログラムなのですが、 この「名称」にダブルクォーテーションが入ることがあり、その場合に「構文が不正です」エラーで途中でこけてしまいます。 このような場合、どのように対処すれば宜しいのでしょうか? 宜しくお願い致します。 Len_Shohin = fxMidB(dread("名称"), 30) Len_Koumoku = fxMidB(dread("名称"), 34) Str_Hyouji = StrConv(dread("名称"), VbStrConv.Narrow) com = New OleDb.OleDbCommand("update T_テーブル set 商品名称 = Left(名称, " & Len_Shohin & "), " _ & " 慣用句名称 = Left(名称," & Len_Shohin & "), 項目名称 = Left(名称," & Len_Koumoku & "), " _ & " 一般名 = Left(名称," & Len_Shohin & "), 表示名称 = Left( """ & Str_Hyouji & """,36) " _ & " where オーダコード = '" & dread("オーダコード") & "'" & "") com.Connection = cn com.ExecuteNonQuery()

  • VB2005でACCESSのADO.NETでのテーブル名取得

    VB2005 ACCESSのテーブル名を取得したいのですが、方法をご教示ください。以下のところで悩んでいます。 OpenFileDialog1.Filter = "アクセス ファイル (*.mdb)|*.mdb" OpenFileDialog1.ShowDialog() If OpenFileDialog1.FileName <> "" Then Dim St As String Dim Cn As New System.Data.OleDb.OleDbConnection Dim SQL As System.Data.OleDb.OleDbCommand Dim UserID As String = "Admin" Dim Password As String = "" Dim MDBFile As String = OpenFileDialog1.FileName Dim N As String = Microsoft.VisualBasic.Right(MDBFile, 9) St = "Provider=""Microsoft.Jet.OLEDB.4.0"";" St &= "Data Source=""" & MDBFile & """;" St &= "User ID=" & UserID & ";" St &= "Jet OLEDB:Database Password=" & Password Cn.ConnectionString = St SQL = Cn.CreateCommand    Cn.Open() この後テーブル名までたどり着けません DataTable  Cn.GetSchema Cn.GetOleDbSchemaTable( "restrictions") などヘルプなどから試みていますが、これらのコーディング法がわかりません。 テーブル名がわかっている(サンプルのPubs の "Publisher")場合はデータセットからはフィールド名が取得できたのですが・・・ よろしくお願いいたします。

  • アクセスDbのテーブル名の取得(VB2005)

    再度の質問です アクセスDBのテーブル名を取得したのですが、方法をご教示ください。DAOでは tabledefsでとれたのですが・・ 以下のコードで先に進めません。 OpenFileDialog1.Filter = "アクセス ファイル (*.mdb)|*.mdb" OpenFileDialog1.ShowDialog() If OpenFileDialog1.FileName <> "" Then Dim St As String Dim Cn As New System.Data.OleDb.OleDbConnection Dim SQL As System.Data.OleDb.OleDbCommand Dim UserID As String = "Admin" Dim Password As String = "" Dim MDBFile As String = OpenFileDialog1.FileName Dim N As String = Microsoft.VisualBasic.Right(MDBFile, 9) St = "Provider=""Microsoft.Jet.OLEDB.4.0"";" St &= "Data Source=""" & MDBFile & """;" St &= "User ID=" & UserID & ";" St &= "Jet OLEDB:Database Password=" & Password Cn.ConnectionString = St SQL = Cn.CreateCommand Cn.Open() Dim tbl As DataTable tbl = Cn.GetOleDbSchemaTable(OleDb.OleDbSchemaGuid.Tables, New Object() {Nothing, Nothing, Nothing, "TABLE"}) ここでtblを見ると TABLE_CATALOG _SCHEMA _NAME _TYPE ・・・DATE_MODIFIED などは見えるのですが、これがDB内のテーブル数だけ繰り返されます。 取得したいのは、TABLE_NAME に ある 例えば "Pub-ID"に相当する内容なのですが、HELPで探しても、その方法がわかりません、ぜひ教えてください。よろしくお願いいたします。

  • VB.NETでテーブルを作成

    VB.NETとAcceseを使用してフォームの入力内容に基にボタンをしてDBにテーブルを作成するプログラムを作成していますが上手くいきません。 どのようにすれば上手くいくのか教えてください。 よろしくお願いします。 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim Cn As New OleDb.OleDbConnection() Cn.ConnectionString = "Provider=Microsoft.Jet.OleDb.4.0;Data Source=" & Application.StartupPath & "\products.mdb" Cn.Open() Dim mysql As New OleDb.OleDbCommand() mysql.Connection = Cn mysql.CommandText = "CREATE TABLE '" & TextBox1.Text & "' ('" & TextBox2.Text & "' '" & ComboBox1.Text & "' NOT NULL,'" & TextBox2.Text & "' '" & ComboBox2.Text & "','" & TextBox3.Text & "' '" & ComboBox3.Text & "',PRIMARY KEY('" & TextBox1.Text & "'))" Cn.Close() End Sub

  • vb.net で ADO でアクセスのテーブル

    アクセスのテーブルのレコードの数を取得したいのですが コードがわからないので続きを教えていただけますか? Imports System.Data.OleDb Sub test() Dim oleConn As OleDbConnection Dim oleCmd As OleDbCommand Dim oleAdp As OleDbDataAdapter oleConn = New OleDbConnection("Provider = Microsoft.ACE.OLEDB.12.0;" & "Data Source=C:\Database1.accdb;") oleCmd = oleConn.CreateCommand() oleCmd.CommandText = "SELECT * FROM テーブル1" oleAdp = New OleDbDataAdapter(oleCmd) 'MsgBox oleCmd.??? End Sub までできたのですが、ここからどうすれば数を取得できますか?

  • sqlでのIIFの使用方法

    accsessのテーブルデータで4列10000レコードのデータを作成し 先頭列にチェックボックスを配置したうえでvb2008 express editionで作成したソフトのdatagridview上でデータを表示し、使う人がチェックボックスをチェックすることにより、選択したレコードデータを別ファイルに保存できるようにしています。mdbのテーブル名は"No1"です。データ連結はdatatableを使用しています。そこで、datagridviewのチェックボックスの変化をmdbテーブルに反映させる処理をdatagridviewのcellcontentclickイベントに Dim Cn As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & basePath) Dim SQLCM As OleDbCommand = Cn.CreateCommand SQLCM.CommandText = "UPDATE No1 SET iif(チェック = False, チェック = True , チェック = False) WHERE ID = " & e.RowIndex + 1 Cn.Open() SQLCM.ExecuteNonQuery() Cn.Close() と書き込んで処理しようとしていますが、UPDATEステートメント構文エラーと表示され処理できません。TRUEに変更する処理は Dim Cn As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & basePath) Dim SQLCM As OleDbCommand = Cn.CreateCommand SQLCM.CommandText = "UPDATE No1 SET チェック = True WHERE ID = " & e.RowIndex + 1 Cn.Open() SQLCM.ExecuteNonQuery() Cn.Close() でうまくいってます。IIFの使用方法が間違っていると思うのですが。どなたかお教えねがえないでしょうか。開発環境は、Vista Home premium、mdbはaccess2003で作成しています。

  • SQLを連続発行する時の正しい(?)書き方は?

    Microsoft Visual Basic 2010 Express の質問です。 ExcelVBAや、AccessVBAで作成したプログラムを、VBに移そうと思っています。 ネットや本のサンプルを、自分のやりたいことに修正しつつ、一応、動作としては希望通りなのですが、元々VBAで簡易に作ったものだけに、本来なら注意すべきインスタンスの管理などがおざなりになっています。 動作は一応正常ですが、果たしてこれで良いのか不安でもありますので質問させていただきます。 大抵の本やサンプルには、複数のSQLを連続で発行するようなものは載っていませんが、いくつものSQLを順次発行していく処理をする時は、どのように記述するのが正しいでしょうか? 例えば、Access2010データベース、C:\test.accdb には、別のテーブルからリンクしたテーブル genpon があるとします。これをコピーしたテーブル、tb01を作る場合、 ------------------------------------ Dim com As OleDb.OleDbCommand Dim cn As OleDb.OleDbConnection = New OleDb.OleDbConnection( _ "Provider=Microsoft.ACE.OLEDB.12.0;" & _ "Data Source=C:\test.accdb;") cn.Open() ''現在のデータを削除 com = New OleDb.OleDbCommand("DROP TABLE [tb01];", cn) com.ExecuteNonQuery() ''現在のデータを削除 com = New OleDb.OleDbCommand("SELECT * INTO [tb01] FROM [genpon];", cn) com.ExecuteNonQuery() ------------------------------------ SQLとしては、現テーブルをDROPして、SELECT * INTO を発行すれば希望通りで、上記もその通り動きますが、NEWでインスタンス作成を繰り返しているのは、やってはいけない事ではないでしょうか? さらに、例えばこのコードの続きとして、FOR~NEXTや、DO~LOOPで繰り返しを設け、その中でINSERT INTO を発行しながら、データを登録するような処理を加える場合、このままでは NEWをループの回数分、繰り返す事になります。 プロシージャの中で、ループなどで複数のSQLを発行する場合、記述として正しい作法がありましたら、教えてください。

  • VB2010とアクセスの接続方法

    textboxにID入力し、ENTERを押したらそのIDのデータがアクセスのデータベースから出力される、というプログラムを書き方のヒントを教えていただけないでしょうか。 Imports System.Data.OleDb Public Class Form1 Private Sub Enter(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Enter '▼データの取得 Dim Cn As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Database\Animals.mdb") Dim SQLCm As OleDbCommand = Cn.CreateCommand Dim Adapter As New OleDbDataAdapter(SQLCm) Dim Table As New DataTable SQLCm.CommandText = "SELECT * FROM T_akusesu" Adapter.Fill(Table) '▼データの連結 textbox.DataBindings.Add("Text", Table, "名前") textbox2.DataBindings.Add("Text", Table, "フリガナ") Table.Dispose() Adapter.Dispose() SQLCm.Dispose() Cn.Dispose() End Sub End Class ・アクセスデータ  ID、名前、氏名 以上、よろしくお願い致します。

  • エクセルVBAでアクセスのテーブルインポート

    VBA初心者です。 エクセルのVBAでデータベースA.mdbのテーブルAをデータベースb.mdbにインポートするプログラムお教えて下さい。 '================================================ sub インポート () Set cn = New Connection'データベース接続 cn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" _ & "Data Source="C:\A.mdb" ●ここにPG書くような感じだと思いますが。   cn.Close: Set cn = Nothing'後処理 End Sub '================================================ もし難しい場合、アクセスのVBAでインポートをするが、この実行をエクセルでするよなのでもいいです。この場合は、インポートされるb.mdb側のプログラムをエクセルで実行するようにしたいです。(A.mdbは多数あるため、変更が大変なため) よろしくお願い致します。

  • VB2008プログラミング(データベース)

    VB2008でプログラムをしています。 データベースのSQL文でエラーが解決できません。 どなたか教えてください。 -内容ー データベースにテーブルを追加したいのですが、フィールド名に半角(No)を使うとエラーになります。 全角(No)に変えるだけでエラーはなくなりますがその理由がわかりません。 <エラー> Com = New OleDb.OleDbCommand("CREATE TABLE 物件(No INTEGER), cn) Com.ExcuteNonQuery() <正常>    Com = New OleDb.OleDbCommand("CREATE TABLE 物件(No INTEGER), cn) Com.ExcuteNonQuery()

専門家に質問してみよう