2010年07月14日


スレッドを呼び出して、そのスレッドの終了を待つ「Join」メソッド

待たない
Imports System.Threading

Module MyModule

' ********************************************************
' 呼び出したスレッドの終了を待たない
' ********************************************************
Sub Main()

	' スレッドインスタンスの作成
	Dim thread As Thread = New Thread(AddressOf ThreadSub)

	' スレッドを開始します
	thread.Start()

	' サブスレッドが終了する前に終了します
	Console.WriteLine("メインスレッドを終了します")

End Sub

Sub ThreadSub()

	Console.WriteLine("ThreadSub")
	Console.ReadLine()

	Console.WriteLine("サブスレッドを終了します")

End Sub

End Module

待つ
Imports System.Threading

Module MyModule

' ********************************************************
' 呼び出したスレッドの終了を待つ
' ********************************************************
Sub Main()

	' スレッドインスタンスの作成
	Dim thread As Thread = New Thread(AddressOf ThreadSub)

	' スレッドを開始します
	thread.Start()

	' サブスレットの終了を待つ
	thread.Join()

	' サブスレッドが終了する前に終了します
	Console.WriteLine("メインスレッドを終了します")

End Sub

Sub ThreadSub()

	Console.WriteLine("ThreadSub")
	Console.ReadLine()

	Console.WriteLine("サブスレッドを終了します")

End Sub

End Module



posted by at 2010-07-14 21:32 | VB.NET Framework2.0 | このブログの読者になる | 更新情報をチェックする

2010年07月05日


VB.net : 印刷コントロール / ブレイクを含めた行あふれの制御


ブラウザでダウンロード
PHP : TCPDF で業務系コントロールブレイク連続帳表印字サンプル をVB.net へ
単純に移植したものですが、行あふれのコントロールを一行づづ対応する方法なの
で、イベントとして呼ばれた時に「ページ」が確定する処理とあまり相性が良くあ
りません。

実際は、一時ファイル等にページコントロールの完了した状態でデータを作成して
から、イベント内では確定したページを印刷したほうが良いでしょう
Imports System.Windows.Forms
Imports System.Drawing

Partial Class Form1

	' 印刷用オブジェクトと変数
	Private pf As Font = New Font("MS 明朝", 12)
	Private pfTitle As Font = New Font("MS 明朝", 24, FontStyle.Bold )

	' 印刷用デバイスコンテキスト
	Private prContext As System.Drawing.Graphics

	' マージン
	Private TopMargin As Integer
	Private LeftMargin As Integer

	Private LineNo As Integer = 0
'	Private LineMax As Integer = 26
	Private LineMax As Integer = 28
	Private PageNo As Integer = 1
	Private Ksum As Integer = 0

	Private Rec As Object() = {"","","","","","","","","","","","","","","","",""}
	Private BreakSyozoku As Boolean = False

	Private bRet As Boolean = False
	Private bExit As Boolean = False
	Private bOption As Boolean = False
	Private bMainLineOverSum As Boolean = False
	Private bMainLineOverHead As Boolean = False

	' RDBMS 共通のインターフェイス
	Private db As lightbox.db.DbInterface = Nothing

	' ******************************************************
	' 印刷の前処理
	' ******************************************************
	Private Sub pd_BeginPrint(ByVal sender As System.Object, _
	ByVal e As System.Drawing.Printing.PrintEventArgs)

'		MessageBox.Show("印刷の前処理を開始します")

		' データベース用インスタンス作成
		' 実際の印刷時にも呼ばれるので1度だけ実行するようにします
		if db is Nothing then
			Dim dbpath As String

			' MDB の場所を取得
			dbpath = Application.StartupPath
			dbpath = dbpath + "\販売管理C.mdb"
	
'			MessageBox.Show(dbpath)
	
			' MDB 用インスタンス作成
			db = New lightbox.db.DbAccess(dbpath)

		end if

		' データベース接続
		' ※ 但し、通常の業務アプリではプログラム起動時に接続するのが通常です
		If Not db.Connect() Then
			MessageBox.Show(db.myError)
			e.Cancel = True
			Return
		End If

		Dim Query as String = "select 社員マスタ.*,コード名称マスタ.*" + _
			" from 社員マスタ left outer join コード名称マスタ" + _
			" on 社員マスタ.所属 = コード名称マスタ.コード " + _
			" where コード名称マスタ.区分 = 2" + _
			" order by 所属"

		' レコードセットを取得
		if Not db.Query( Query ) then
			MessageBox.Show(db.myError)
			e.Cancel = True
			Return
		end if

		' 用意したレコードセットにデータが無い場合印字処理を行わない
		if Not Ctype(db,lightbox.db.DbAccess).myReader.HasRows then
			MessageBox.Show("印字データが存在しません")
			e.Cancel = True
			Return
		end if

	End Sub

	' ******************************************************
	' 印刷の後処理
	' ******************************************************
	Private Sub pd_EndPrint(ByVal sender As System.Object, _
	ByVal e As System.Drawing.Printing.PrintEventArgs)

'		MessageBox.Show("印刷の後処理を開始します")

		' 接続解除
		if Not db is Nothing then
			db.Close()
		end if

	End Sub

	' ******************************************************
	' 実際の印刷処理
	' ******************************************************
	Private Sub pd_PrintPage(ByVal sender As System.Object, _
	ByVal e As System.Drawing.Printing.PrintPageEventArgs)

		e.HasMorePages = False
		bExit = False

		' 印刷に必要なデータを取得します
		GetContectData(e)

		' 固定データ( ここではヘッダとマージン境界線
		PrForm(e)

		' 初回の読み出し
		if PageNo = 1 then
			bRet = db.Read()
		end if
		if bOption then
			bOption = False
			UserBreakHeader(1)
		end if

		Do While bRet

			if Rec(3).ToString <> db.GetValue("所属") then
				BreakSyozoku = True
			end if

			' bMainLineOverSum は、再入した場合のスキップフラグ
			if not bMainLineOverSum then
				' 合計印字 : 初回以外のブレイク発生時
				if BreakSyozoku and  Rec(3).ToString <> "" then
					UserBreakSum()
					if bExit then
						PageNo += 1
						e.HasMorePages = True
						Exit Do
					end if
				end if
			end if

			if LineNo > LineMax then
				' この脱出でヘッダーを印字してループに再入して明細印字に移行する
				PageNo += 1
				e.HasMorePages = True
				' ここより前のブレイク処理で行あふれした場合があるので
				' ここより以前のブレイク処理をスキップする
				bMainLineOverSum = True
				Exit Do
			End IF

			' ここでは、bMainLineOverHead は必要ありません
			if not bMainLineOverHead then
				' ページの最初と、ブレイク発生時
				if LineNo = 6 or BreakSyozoku then
					UserBreakHeader()
					if bExit then
						PageNo += 1
						e.HasMorePages = True
						' 再入した場合ここより以前のブレイク処理をスキップする
						bMainLineOverSum = True
						Exit Do
					end if
				end if
			end if


			bMainLineOverSum = False
			bMainLineOverHead = False

			PrString( LineNo, 0, db.GetValue("社員コード") )
			PrString( LineNo, 100, db.GetValue("氏名") )

			Dim StrKingaku As String = "         " + Integer.Parse(db.GetValue("給与")).ToString("#,0")
			StrKingaku = StrKingaku.Substring( StrKingaku.Length - 9 )
			PrString( LineNo, 356, StrKingaku )

			' 集計処理
			Ksum += Integer.Parse(db.GetValue("給与"))


			LineNo += 1

			' レコードの保存
			Ctype(db,lightbox.db.DbAccess).myReader.GetValues(Rec)

			' ブレイクフラグのリセット
			BreakSyozoku = False


			bRet = db.Read()
			if Not bRet then
				Exit Do
			end if

		Loop

		if Not bRet then
			UserBreakSum()
			if bExit then
				PageNo += 1
				e.HasMorePages = True
			end if
		end if

	End Sub

	' ******************************************************
	' 所属ブレイクヘッダ
	' ******************************************************
	Private Sub UserBreakHeader(Optional ByVal Opt As Integer = 0)
	
		' 最終行にブレイクヘッダのみ印字しない
		' ( よって、次に印字する行が最終行の場合は改ページ )
		if LineNo > LineMax - 1 then
			bExit = True
			Exit Sub
		end if

		PrString( LineNo, 0, "所属" )
		if Opt = 0 then
			PrString( LineNo, 70, db.GetValue("名称") )
		else
			PrString( LineNo, 70, Rec(13).ToString() )
		end if
	
		' 次の印字行
		LineNo += 1

	End Sub

	' ******************************************************
	' 所属ブレイク合計
	' ******************************************************
	Private Sub UserBreakSum()

		' 改ページ条件では、ブレイクヘッダが必要
		if LineNo > LineMax then
			bExit = True
			bOption = True
			Exit Sub
		end if

		PrString( LineNo, 300, "合計" )

		Dim StrKingaku As String = "         " + Ksum.ToString("#,0")
		StrKingaku = StrKingaku.Substring( StrKingaku.Length - 9 )
		PrString( LineNo, 356, StrKingaku )

	
		' 集計データを使用したので、初期化
		Ksum = 0
	
		' 次の印字行
		LineNo += 1

	End Sub

	' ******************************************************
	' 印字に必要なデータの取得
	' ******************************************************
	Private Sub GetContectData(ByVal e As System.Drawing.Printing.PrintPageEventArgs)

		' 左側余白
		LeftMargin = e.MarginBounds.Left
		' 上側余白
		TopMargin = e.MarginBounds.Top
		' 現在のコンテキストを取得
		prContext = e.Graphics

	End Sub

	' ******************************************************
	' 文字列を指定行の先頭から印字
	' ******************************************************
	Private Sub PrString(ByVal row As Integer, _
		ByVal x As Integer, _
		ByVal str As String, _
		Optional ByVal TargetFont As Font = Nothing)

		if TargetFont is NOthing then
			TargetFont = pf
		end if

		Dim yPos As Integer = 0
		' フォントの高さで一行の高さを決定
		yPos = TopMargin + (row - 1) * (pf.GetHeight(prContext)+6)
		' 印字可能な左端から文字列をセットする
		prContext.DrawString(str, TargetFont, Brushes.Black, LeftMargin + x, yPos)

	End Sub

	' ******************************************************
	' ページ固定データ印字
	' ※ ヘッダ印字と同等
	' ******************************************************
	Private Sub PrForm(ByVal e As System.Drawing.Printing.PrintPageEventArgs)

		PrString( 1, 20, "** 所属別支給額合計表 **", pfTitle )

		Dim StrPage As String = "   " + PageNo.ToString("#,0")
		StrPage = StrPage.Substring( StrPage.Length - 3 )
		PrString( 1, 530, "page : " + StrPage )

		PrString( 4, 0, "社員コード" )
		PrString( 4, 100, "氏名" )
		PrString( 4, 400, "給与" )

		' 上部上限ライン
		prContext.DrawLine( _
		 Pens.Black, _
		 LeftMargin, _
		 TopMargin, _
		 LeftMargin + (e.PageBounds.Width - 2 * LeftMargin), _
		 TopMargin _
		 )

		' 左側ライン
		prContext.DrawLine( _
		 Pens.Black, _
		 LeftMargin, _
		 TopMargin, _
		 LeftMargin, _
		 TopMargin + (e.PageBounds.Height - 2 * TopMargin) _
		 )

		' 右側ライン
		prContext.DrawLine( _
		 Pens.Black, _
		 LeftMargin + (e.PageBounds.Width - 2 * LeftMargin), _
		 TopMargin, _
		 LeftMargin + (e.PageBounds.Width - 2 * LeftMargin), _
		 TopMargin + (e.PageBounds.Height - 2 * TopMargin) _
		 )

		' 下部下限ライン
		prContext.DrawLine( _
		 Pens.Black, _
		 LeftMargin, _
		 TopMargin + (e.PageBounds.Height - 2 * TopMargin), _
		 LeftMargin + (e.PageBounds.Width - 2 * LeftMargin), _
		 TopMargin + (e.PageBounds.Height - 2 * TopMargin) _
		 )

		' 次に印字する行
		LineNo = 6

	End Sub


End Class



posted by at 2010-07-05 21:42 | VB.NET Framework2.0 | このブログの読者になる | 更新情報をチェックする
Seesaa の各ページの表示について
Seesaa の 記事がたまに全く表示されない場合があります。その場合は、設定> 詳細設定> ブログ設定 で 最新の情報に更新の『実行ボタン』で記事やアーカイブが最新にビルドされます。

Seesaa のページで、アーカイブとタグページは要注意です。タグページはコンテンツが全く無い状態になりますし、アーカイブページも歯抜けページはコンテンツが存在しないのにページが表示されてしまいます。

また、カテゴリページもそういう意味では完全ではありません。『カテゴリID-番号』というフォーマットで表示されるページですが、実際存在するより大きな番号でも表示されてしまいます。

※ インデックスページのみ、実際の記事数を超えたページを指定しても最後のページが表示されるようです

対処としては、このようなヘルプ的な情報を固定でページの最後に表示するようにするといいでしょう。具体的には、メインの記事コンテンツの下に『自由形式』を追加し、アーカイブとカテゴリページでのみ表示するように設定し、コンテンツを用意するといいと思います。


※ エキスパートモードで表示しています

アーカイブとカテゴリページはこのように簡単に設定できますが、タグページは HTML 設定を直接変更して、以下の『タグページでのみ表示される内容』の記述方法で設定する必要があります

<% if:page_name eq 'archive' -%>
アーカイブページでのみ表示される内容
<% /if %>

<% if:page_name eq 'category' -%>
カテゴリページでのみ表示される内容
<% /if %>

<% if:page_name eq 'tag' -%>
タグページでのみ表示される内容
<% /if %>
この記述は、以下の場所で使用します