さて、ネットにあるテキストドキュメントをダウンロードしてディスクに保存するプログラムを作ったので紹介する。
まずは名前空間のインポートを行う。
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