dat保存プログラムができたところ
Forever1 = AppPath & "\File\" & Ar1(i, 7)
Forever2 = AppPath & "\File\" & Ar1(i, 7) & "\" & Ar1(i, 8)
If Not fs.folderexists(Forever1) Then
fs.createfolder(Forever1)
End If
If Not fs.folderexists(Forever2) Then
fs.createfolder(Forever2)
End If
ft = fs.createtextfile(Forever2 & "\" & Ar1(i, 8) & ".dat")
ft.write(S1)
ft.close()
ADOを使いこなせるプログラマーも.NETをやるからにはADO.NETへの移行が必要だ。
ADOはCOMコンポーネントゆえの制限があるので.NETクラスのADO.NETを使う必要があるということだ。
ADO.NETはADOとはまったく違うので習得はそれなりの手間だ。それでADOを使い続けるプログラマーも多いと思うが、
ADO.NETを2日勉強すればADO.NETの便利な部分に魅せられることだろう。
ADOに限界を感じるのはサーバーにアクセスが増えてきたときだ。ADOはシングルスレッドのCOMコンポーネントなのでアクセスの多いサーバーではマルチスレッドのADO.NETが良い。
-------------------------------
'レコード削除
Dim conn As New SqlConnection(ConnectionString)
Dim SQL As String
SQL = "Delete From Categories2 where CategoryID=@CategoryID"'←SQL文に変数を埋め込める名前付きパラメータ@〜は便利
Dim cmd As New SqlCommand(SQL, conn)
cmd.Parameters.Add("@CategoryID", T3_1.Text)'←パラメータに値をセット
conn.Open()
Dim num As Integer = cmd.ExecuteNonQuery'←numには操作されたレコードの数が返ってくる。
MSG.Text = num
conn.Close()
SQL Server,MSDEの場合はImports System.Data.SqlClient
Accessの場合はImports System.Data.OleDb
を使うが、同じマイクロソフトの製品なのに仕様がかなり違う。
Accessでは@名前付きパラメータが使用できず、?ブレースホルダを使う。
?を1コ使っている例は見つかるが、2コ以上の?を使っている例は検索しても解説ページが見つからなかったので自分で作ってみた。
2コ以上の?を使っている例は現時点ではこの解説が唯一だと自負している。
ブレースホルダ付きSQLステートメントは値をセットする順序が大事で、パラメータ名には支配されない。
SQL文に?が出てきた順にcmd.Parameters.Addで値をセットする。
OLE DBの場合は
SQL="Select _ from TABLE Where Field=" & 変数
としてブレースホルダを使わない方が良いような気もするが、
cmd.Parameters.Addはユーザに入力して欲しくない特殊文字を自動的にエスケープしてくれるのでセキュリティ的には有利だ。
とはいえ、各言語やSQLの予約語・特殊文字はそう多くは無いので自前でエスケープしてOLE DB SQL文には従来の変数代入方式でもよい。
------------------------------------
Dim conn As New OleDbConnection(接続文字列)
Dim SQL As String
SQL = "Update Categories2 Set CategoryName=?,Description=? where CategoryID=?"
Dim cmd As New OleDbCommand(SQL, conn)
cmd.Parameters.Add("CategoryName", 値)'←SQL内の?の順にパラメータをパラメータコレクションに追加
cmd.Parameters.Add("Descriotion", 値)'←
cmd.Parameters.Add("CategoryID", 値)'←
conn.Open()
Dim num As Integer = cmd.ExecuteNonQuery
conn.Close()
いままで
Array(0,0)="1"
Array(0,1)="a"
Array(1,0)="2"
Array(1,1)="b"
と配列で扱っていたものをデータセット内のテーブルとして扱えば実に扱いやすい。
ID 値
1 a
2 b
↑を並び替えるメソッドも用意されているからクイックソートやバブルソートなどのアルゴリズムを書かなくとも並び替えができてしまう。
VB6.0も好きでVB6.0の方が優れている点もかなり多いのだががこういったことを見てしまうと.NETに移行せざるを得ないのである。
ところでプログラミング中に変数の中を見てみたいことがあるが、
その変数が配列だと画面に表示するためには
For i=〜
For j=〜
出力 多次元配列
Next
Next
みたいに配列を総当りで読み込むプログラムが必要だ。
しかしデータをデータセットで扱っていたなら
デバッグ用データグリッドコントロールのデータソース = データセット
としてデータグリッドにデータをバインド(連結)表示させるだけだ。
記事を読み込むプログラム。
Dim myWeb As New WebClient
Dim b() As Byte
b = myWeb.DownloadData(URL)
Dim bStr As String = Encoding.UTF8.GetString(b)
画像などのファイルの場合はbのバイナリのままでよいが、掲示板の記事は文字列bStrに変換。
これが.NETのWebClientを使ったときのインターネットドキュメント取得方法である。
上記クラスを使うときは名前空間
System.Net
System.Text
をインポートします。
System.Net=WebClientクラス用
System.Text=文字コードのエンコード用
さて、ネットにあるテキストドキュメントをダウンロードしてディスクに保存するプログラムを作ったので紹介する。
まずは名前空間のインポートを行う。
Imports System.Net
Imports System.Text
Imports System.IO
---------------
サーバへの送受信を行うクラスを使用する。
Dim WC As New WebClient
このクラスは先ほどインポートしたSystem.Netに含まれているものだ。
---------------
そしてアドレス文字列を準備する。
Dim UStr As String = "とりこみ対象ページのアドレス"
たとえばhttp://www.abcd.net/efg.htmlなど。
-----------------------------------------
ネットドキュメントをバイナリデータとして読み込む。
Dim DownLoadData As Byte() = WC.DownloadData(UStr)
-----------------------------------
今回はEUCコードのページをUTF-8に変換する例を挙げておく。
Dim UTF8Bytes As Byte() = Encoding.Convert(Encoding.GetEncoding("EUC-JP"), Encoding.UTF8, DownLoadData)
(画像ファイルなどはこのコード変換作業は不要だ。WindowsXPではUTF-8のドキュメントが扱いやすいようなのでUTF-8にしてみた。私がフランス語やドイツ語も使うこともあるのであえてShift-JISは見送った。)
----------------
エンコード後のバイナリデータをディスクに書き込むところ。
Dim fs As New FileStream(AppPath & "\DownLoad.html", FileMode.Create)
Dim w As New BinaryWriter(fs)
w.Write(UTF8Bytes)
w.Close()
fs.Close()
Dtというメモリ内テーブルが定義されていたとする。
その列(フィールド、カラムともいう)のコレクションを得るにはどうするか?
Dim DC() as DataColumn
のなかにテーブル内の列情報を格納することはできないのだ。
DataColumnCollectionというオブジェクトがありそれに代入する。
Dim DC as DataColumnCollection
DC=Dt.Columns
これで列コレクションをテーブルから独立して扱えるようになった。
そのあとは
dim dc2 as datacolumn
For each dc2 in DC
列名取得
列に定義されているデータタイプ取得
Next
前回はDataTableのテーブル構造をSQL Serverに自動作成するプログラムを書いた。
次はSQL Serverのテーブル構造をDataTableなどに自動作成するために必要なスキーマの取得をしてみる。
Dim CS As String = "Data Source=(local);Initial Catalog=Keiba;User ID=kimagure;Password=kimagure"
Dim conn As New SqlConnection(CS)
Dim SQL As String
SQL = "Select * From Race Where ID=20000105100000"
Dim cmd As SqlCommand = New SqlCommand(SQL, conn)
conn.Open()
Dim DR As SqlDataReader = cmd.ExecuteReader
DR.Read()
Dim schemaTable As DataTable = DR.GetSchemaTable()
Dim myRow As DataRow
Dim myCol As DataColumn
SS = ""
For Each myRow In schemaTable.Rows
For Each myCol In schemaTable.Columns
SS = SS & myCol.ColumnName & " = " & myRow(myCol).ToString() & CL
Next
Next
DF_.RTB1.Text = SS : DF_.Show()
LnanComp2:
DR.Close()
conn.Close()
LandComp:
Button1.Enabled = True
App.DoEvents()
DataGridの任意の列の幅を変更するコードを作ってみた。
DataGridには
dim Dt2 as new DataTable("Dt2")
とDt2という名前のデータテーブルを作ってそれを表示する。
そしてDt2にはColumns.AddやDt2.Rows.Add(DataRow)で列と行が追加してある。
今回存在する列名はo、oSの2つであるとする。
参考:Dt2.Columns.Add("o",gettype(Single))
↑oというなまえの列をSingle数値型で追加
Dt2の列を定義したらデータグリッドの列幅も操作できる。
Dim ts As New DataGridTableStyle
ts.MappingName = Dt2.TableName
Dim DTS As DataGridTableStyle
Dim StyleName As String
Dim StyleExist As Short = 0
For Each DTS In DataGrid1.TableStyles
StyleName = DTS.MappingName
If StyleName = "Dt2" Then StyleExist = 1
Next
If StyleExist = 0 Then
DataGrid1.TableStyles.Add(ts)
End If
テキストボックス内の文字列の一番右にカーソルがあるときに→キーを押すと次のテキストボックスにフォーカスが移動する例
Dim T As TextBox
T = CType(sender, TextBox)
If e.KeyCode = Keys.Right Then
If T.SelectionStart = T.Text.Length Then
o2.Focus()
End If
End If
Dim ConnectionString As String = "Data Source=(local);Initial Catalog=Northwind;Integrated Security=SSPI;"
Dim SQL As String = "Select * From Products"
Dim conn As New SqlConnection(ConnectionString)
Dim cmd As New SqlCommand(SQL, conn)
conn.Open()
Dim DR As SqlDataReader = cmd.ExecuteReader
GridView1.DataSource = DR
GridView1.DataBind()
DR.Close()
conn.Close()
Visual Web Developer 2005 Express Editionという無料のサーバーサイドアプリ開発ツールをインストールすると
SQL Server 2005 Express Editionも同時にインストールされる。
そのあとさらにマイクロソフトのページに行き
Microsoft SQL Server 2005 Express Edition with Advanced Services
をインスコする。
そうするとWindowsのスタート→プログラムメニューに
SQL Server 2005 Management Studio Express
のショートカットができる。これはなにかというと、上位SQL ServerのEnterprise Manegerのようなものでグラフィカルにデータベースを操作できるのだ。
Dim ConnectionString As String = "Data Source=.\sqlexpress;Initial Catalog=DATABASE.MDF;Integrated Security=SSPI;"
Dim SQL As String = "Select * From aaa"
Dim conn As New SqlConnection(ConnectionString)
Dim cmd As New SqlCommand(SQL, conn)
conn.Open()
Dim DR As SqlDataReader = cmd.ExecuteReader
GridView2.DataSource = DR
GridView2.DataBind()
DR.Close()
conn.Close()
dim Dt as new DataTable("Dt")
'Const adSchemaTables = 20
Dim ConnectionString As String = "Data Source=.\sqlexpress;Initial Catalog=MyDataBase;Integrated Security=SSPI;"
Dim conn As New SqlConnection(ConnectionString)
ハードディスクの中身をしるにはフォルダの階層構造とフォルダの中のファイルを取得するわけであるが、
それと同じ要領でデータベースの構造とデータを取得したわけである。
これができれば、データベースの移動、コピー、バックアップができる。
したがって、SQL Server 2005 Express EditionからSQL Server 2000などへデータを移行できるようになった。
.NET2.0でテーブル構造取得プログラムを作ってみた。
Dim ConnectionString As String = "Data Source=.\sqlexpress;Initial Catalog=DATABASE.MDF;Integrated Security=SSPI;"
Dim SQL As String = "Select Top 1 * From ESODATA"
Dim conn As New SqlConnection(ConnectionString)
Dim cmd As New SqlCommand(SQL, conn)
conn.Open()
Dim DR As SqlDataReader = cmd.ExecuteReader
DR.Read()
Dim schemaTable As DataTable = DR.GetSchemaTable()
Dim myRow As DataRow
Dim myCol As DataColumn
Dim SS As String = ""
For Each myRow In schemaTable.Rows
For Each myCol In schemaTable.Columns
SS = SS & myCol.ColumnName & " = " & myRow(myCol).ToString() & "<br>"
Next
SS += "----------------------------------------------" & "<br>"
Next
DR.Close()
conn.Close()
Label2.Text = SS
Dim ConnectionString As String = "Data Source=.\sqlexpress;Initial Catalog=DATABASE.MDF;Integrated Security=SSPI;"
TableName = ""
Dim SQL As String = "Create Table TABLU (Field1 datetime,Field2 nvarchar(50))" 'datetime型を作るときにはサイズを指定しない
Dim conn As New SqlConnection(ConnectionString)
Dim cmd As New SqlCommand(SQL, conn)
conn.Open()
Dim num As Integer = cmd.ExecuteNonQuery
conn.Close()
Dim ConnectionString As String = "Data Source=.\sqlexpress;Initial Catalog=DATABASE.MDF;Integrated Security=SSPI;"
Dim SQL As String = "Select Top 1 * From " & TableName
Dim conn As New SqlConnection(ConnectionString)
Dim cmd As New SqlCommand(SQL, conn)
conn.Open()
Dim DR As SqlDataReader = cmd.ExecuteReader
DR.Read()
Dim schemaTable As DataTable = DR.GetSchemaTable()
Dim myRow As DataRow
Dim myCol As DataColumn
Dim SS As String = ""
Dim SQL2 As String
SQL2 = "Create Table " & TableName & " ("
For Each myRow In schemaTable.Rows
Dim c1 As Integer
If Not c1 = 0 Then
SQL2 += ","
End If
Dim DType As String = ""
Dim Size As Integer
For Each myCol In schemaTable.Columns 'AAAAAAAAAAAAAAAAAAAA
'SS = SS & myCol.ColumnName & " = " & myRow(myCol.ColumnName).ToString() & "<br>"
If myCol.ColumnName = "ColumnName" Then
SQL2 += myRow(myCol.ColumnName).ToString
End If
If myCol.ColumnName = "ColumnSize" Then
Size = myRow(myCol.ColumnName)
End If
If myCol.ColumnName = "DataType" Then
Select Case myRow(myCol.ColumnName).ToString
Case "System.String"
DType = "nvarchar"
SQL2 += " " & DType & "(" & Size & ")"
Case "System.Int64"
DType = "bigint"
SQL2 += " " & DType
Case "System.DateTime"
DType = "datetime"
SQL2 += " " & DType
End Select
End If
'サイズ取得のほうがタイプ取得より前なのでここに書くと失敗
'If myCol.ColumnName = "ColumnSize" Then
' If DType = "nvarchar" Then
' SQL2 += "(" & myRow(myCol.ColumnName).ToString & ")"
' Else
' End If
'End If
Next 'AAAAAAAAAAAAAAAAAAAA
SS += "----------------------------------------------" & "<br>"
c1 += 1
Next
SQL2 += ")"
DR.Close()
conn.Close()
Label3.Text = SQL2
Dim ConnectionString2 As String = "Data Source=(local);Initial Catalog=AoM;Integrated Security=SSPI;"
Dim conn2 As New SqlConnection(ConnectionString2)
Dim cmd2 As New SqlCommand(SQL2, conn2)
conn2.Open()
Dim num2 As Integer = cmd2.ExecuteNonQuery
conn2.Close()
'↑ここまでがコピー先データベースのテーブル設計が終わった段階である。つぎはデータのコピーを行う。
↑の方ではテーブルの構造をコピーしたので今度はデータをコピーするプログラム。
'データベースA→データリーダーに読み込み→データベースBに書き込み
ConnectionString = "Data Source=.\sqlexpress;Initial Catalog=DATABASE.MDF;Integrated Security=SSPI;"
ConnectionString2 = "Data Source=(local);Initial Catalog=AoM;Integrated Security=SSPI;"
SQL = "Select * From " & TableName
conn = New SqlConnection(ConnectionString)
conn2 = New SqlConnection(ConnectionString2)
cmd = New SqlCommand(SQL, conn)
conn.Open()
DR = cmd.ExecuteReader
DR.Read()
schemaTable = DR.GetSchemaTable()
SS = ""
Dim i As Integer
'For Each myRow In schemaTable.Rows
' SQL2 = "Insert into " & TableName & "("
' For Each myCol In schemaTable.Columns
' 'SS = SS & myCol.ColumnName & " = " & myRow(myCol).ToString() & "<br>"
' Next
' 'SS += "----------------------------------------------" & "<br>"
'Next
Dim SQL2b As String
'While DR.Read 'WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW'いったんリードしてるのでここではリードしない
Do
SQL2 = "Insert into " & TableName & "("
SQL2b = ") Values ("
For i = 0 To DR.FieldCount - 1
If Not i = 0 Then
SQL2 += ","
SQL2b += ","
End If
SQL2 += "[" & DR.GetName(i) & "]"
'文字列は' 'で囲むので列のタイプがわからないといけない。
schemaTable = DR.GetSchemaTable()
For Each myRow In schemaTable.Rows
For Each myCol In schemaTable.Columns
If myCol.ColumnName = "DataType" Then
If myRow(myCol.ColumnName).ToString = "System.DateTime" Or myRow(myCol.ColumnName).ToString = "System.String" Then
If Not IsDBNull(DR(i)) Then
SQL2b += "'" & DR(i) & "'"
Else
SQL2b += "Null"
End If
End If
GoTo LandB
End If
Next
Next
LandB:
' If schemaTable.Rows(DR.GetName(i))("DataType") Then
'SQL2b += schemaTable.Rows(0)("DataType").ToString
Next
'GoTo LandA
SQL2 += SQL2b & ")"
cmd2 = New SqlCommand(SQL2, conn2)
conn2.Open()
num2 = cmd2.ExecuteNonQuery
conn2.Close()
'End While 'WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
Loop While DR.Read
' GridView5.DataSource = DR
' GridView5.DataBind()
LandA:
DR.Close()
conn.Close()
Label3.Text = SQL2
Dim LinkLove As LinkLabel = New LinkLabel
LinkLove.Name = "LinkLove" & i
LinkLove.AutoSize = True
LinkLove.Text = S2(0)
If i = 1 Then 'HHHHHHHHHHHHHHHHHHHHHH
PX = 0 : PY = 0
Else 'HHHHHHHHHHHHHHHHHHHHHH
Dim o As Object
Dim LB As LinkLabel
For Each o In Me.Controls 'DDDDDDDDDDDDDDDDD
If o.Name = "LinkLove" & i - 1 Then
'CType
LB = CType(o, LinkLabel)
PX = 0
PY = LB.Location.Y + LB.Height
End If 'HHHHHHHHHHHHHHHHHHHHHH
Next 'DDDDDDDDDDDDDDDDD
End If
LinkLove.Location = New Point(PX, PY)
'→エラー'Form1.Controls.Add(LinkLove)'↓Form1でなくMeキーワードを使う
Me.Controls.Add(LinkLove)
'LinkLove.Visible = True
'ListBox2.Items.Add(FileString)
AddHandler LinkLove.LinkClicked, AddressOf LinkLove_LinkClicked
しかし、あるファイルのみをコピーしたいなど細かい制御が必要な場合は
やはりファイルを1コずつ扱うのだ。
-----------------------------------
Dim Moto As String
Dim Saki As String
Moto = "コピー元ディレクトリ"
Saki = "コピー先ディレクトリ"
Dim di As New DirectoryInfo(Moto)
Dim fi As FileInfo() = di.GetFiles()
Dim fiTemp As FileInfo
For Each fiTemp In fi
My.Computer.FileSystem.CopyFile(Moto & "\" & fiTemp.Name, Saki & "\" & fiTemp.Name, True)
Next fiTemp
Process.Startという便利なメソッドがある。
便利だが、単にProcess.Start("http://〜")でサイトを開くとすでに開いているウィンドウに新たなページが表示されてしまう。
新しいウィンドウにページを表示したくば次のようにするのだ。
Dim URL As String
Dim i As Integer
Try
i = ListBox1.SelectedIndex
URL = URLDt.Rows(i)("URL")
Dim myProcess As New ProcessStartInfo
myProcess.FileName = BrowserPath
myProcess.Arguments = URL
myProcess.CreateNoWindow = False
myProcess.UseShellExecute = False
myProcess.Verb = "open"
Process.Start(myProcess)
Catch
String 関数
類似 Space 関数
必要条件
バージョン 1
指定した繰り返し回数を使用して文字列を返します。
String(number, character)
引数
number
文字をいくつ並べるのかを指定します。引数 number に Null 値が含まれる場合は、Null 値を返します。
character
文字の文字コードまたは文字列式を指定します。この文字列の先頭文字を number 回繰り返した値を返します。引数 character に Null 値が含まれる場合は、Null 値を返します。
解説
引数 character に 256 以上の数値を指定すると、String 関数では次の式を使って数値を有効な文字コードに変換します。
character Mod 256
次のコードは、String 関数を使って指定された文字数だけ並べた文字列を返す例です。
Visual Basic コードのコピー
Public Sub CreateMyForm()
' Create a new instance of the form.
Dim form1 As New Form()
' Create two buttons to use as the accept and cancel buttons.
Dim button1 As New Button()
Dim button2 As New Button()
' Set the text of button1 to "OK".
button1.Text = "OK"
' Set the position of the button on the form.
button1.Location = New Point(10, 10)
' Set the text of button2 to "Cancel".
button2.Text = "Cancel"
' Set the position of the button based on the location of button1.
button2.Location = _
New Point(button1.Left, button1.Height + button1.Top + 10)
' Set the caption bar text of the form.
form1.Text = "My Dialog Box"
' Display a help button on the form.
form1.HelpButton = True
' Define the border style of the form to a dialog box.
form1.FormBorderStyle = FormBorderStyle.FixedDialog
' Set the MaximizeBox to false to remove the maximize box.
form1.MaximizeBox = False
' Set the MinimizeBox to false to remove the minimize box.
form1.MinimizeBox = False
' Set the accept button of the form to button1.
form1.AcceptButton = button1
' Set the cancel button of the form to button2.
form1.CancelButton = button2
' Set the start position of the form to the center of the screen.
form1.StartPosition = FormStartPosition.CenterScreen
' Add button1 to the form.
form1.Controls.Add(button1)
' Add button2 to the form.
form1.Controls.Add(button2)
' Display the form as a modal dialog box.
form1.ShowDialog()
End Sub
Dim hProcesses As System.Diagnostics.Process() = System.Diagnostics.Process.GetProcessesByName("notepad") '大文字のNotepadでも機能する
Dim hProcess As System.Diagnostics.Process
For Each hprocess In hProcesses
hProcess.Kill()
Next hProcess
−−−−−−−−−−−−−−−−−−−−−−−−−−
ウィンドウズアクセサリのnotepad.exeを起動するといくつ起動してもすべてnotepadというプロセスネイムなのですべてのメモ帳を終了することができる。
特定のメモ帳だけを制御したいばあいはプロセスIDを採用する。
ByVal e As System.EventArgs) Handles Button3.Click
'指定のExcelファイルを起動しているExcel.EXEを探し終了させる
Dim localByName As Process() = Process.GetProcessesByName("Excel")
Dim p As Process
Dim fn As String = "Microsoft Excel - " & "Test.xls"
'起動中のExcelを取得
For Each p In localByName
'指定のファイル名(Test.xls)で起動中のExcelがあれば終了する
If System.String.Compare(p.MainWindowTitle, fn, True) = 0 Then
'指定のウィンドウにクローズ メッセージを送信して、プロセスを終了
p.CloseMainWindow()
End If
Next
Private Sub MainForm_Load(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles MyBase.Load
Dim txtBox As New TextBox()
txtBox.Location = New System.Drawing.Point(100, 100)
txtBox.Size = New System.Drawing.Size(50, 20)
Me.Controls.Add(txtBox)
txtBox.Show()
End Sub
--------------------------------------------------------------------------------
Say 2002/11/26(火) 22:19:01
VB6ならZOrderで変更できますが、
VB.Netではできませんか?
データテーブル、データカラム、データロー
Dim Dt As New DataTable("iR")
Dim colInt32 As DataColumn = New DataColumn("iR")
colInt32.DataType = System.Type.GetType("System.Int32") 'String型だとソートすると1<16<8とかになる
Dt.Columns.Add(colInt32)
Dim NewRow As DataRow = Dt.NewRow
NewRow("iR") = iR
Dt.Rows.Add(NewRow)
Dim WaitTime As Single
Dim FirstTime As Single
Dim NowTime As Single
WaitTime = 0.1
FirstTime = VB.Timer()
Do
NowTime = VB.Timer()
App.DoEvents()
Loop While (NowTime - FirstTime) >= 0 And (NowTime - FirstTime < WaitTime)