顯示具有 eHrsys 標籤的文章。 顯示所有文章
顯示具有 eHrsys 標籤的文章。 顯示所有文章

2013年7月22日 星期一

[學習] ReportViewer SubReport 子報表

CODE:使用 自定義事件 DemoSubreportProcessingEventHandler

2013年3月24日 星期日

[技巧] 動態更改 ReportViewer.LocalReport.ReportPath


Me.ReportViewer1.Reset()
'組件路徑 (不必將 report檔 ".rdlc" 丟到實際資料夾底下...)
Me.ReportViewer1.LocalReport.ReportEmbeddedResource = "eHRsys.Report2.rdlc"  

Note:
eHRsys.Report2.rdlc
組件名稱.檔案名稱.檔案副檔名

參考:
[MSDN]LocalReport.ReportPath 屬性
如何動態更換ReportViewer的RDLC及DataSource
收藏 RDLC动态绑定问题
如何使用LocalReport - WebForm (3)
动态的rdlc报表
顯示整頁模式
The WinForms ReportViewer and Multiple Report Definition Files
Binding DataSet and Generic *.rdlc Reports to a ReportViewer at Runtime

2013年3月20日 星期三

[學習] ReportViewer Drill-Through Reports 鑽研報表 (大陸譯:钻取报表)

主體屬性 與 報表屬性
報表規格A4紙 21寬 29.7長
邊界都為0


CODE:使用 自定義事件 DemoDrillthroughEventHandler
Imports Microsoft.Reporting.WinForms
Public Class Printer_Salary
    Private orderDetailsData As DataTable = Nothing
    Function LoadOrderDetailsData(ByVal a As String) As DataTable
        Dim salaryM As New Class_conn(ConnRegNfunction.connMode, _
                            ConnRegNfunction.連線字串Local, _
                            ConnRegNfunction.連線字串WebUri)
        Dim salaryDT = salaryM.DataTable("SELECT s.*,e.zhFname + e.zhName as 姓名,b.account FROM dbo.salaryM as s left join dbo.employee as e on s.staff_sn = e.staff_sn left join dbo.bank as b on s.staff_sn = b.staff_sn where s.staff_sn = " & a & " and s.ym = " & ComboBox3.Text.Trim & ComboBox2.Text.Trim & " and s.第幾次發薪 = " & TextBox1.Text.Trim & "", Nothing, Nothing)
        salaryM.Dispose()
        Return salaryDT
    End Function

    Private Sub DemoDrillthroughEventHandler(ByVal sender As System.Object, ByVal e As DrillthroughEventArgs)
        Dim myLocalReport As LocalReport
        myLocalReport = e.Report
        orderDetailsData = LoadOrderDetailsData(myLocalReport.GetParameters()("Report_Parameter_3").Values(0).Trim)
        myLocalReport.DataSources.Add(New ReportDataSource("yiTestDataSet_salaryM1", orderDetailsData))
    End Sub

    Private Sub Printer_Salary_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.ReportViewer1.RefreshReport()
    End Sub

    Private Sub Printer_Salary_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown
        Me.FormBorderStyle = Windows.Forms.FormBorderStyle.FixedSingle

        Dim month() As String = {"01", "02", "03", "04", "05", "06", _
                                    "07", "08", "09", "10", "11", "12"}
        ComboBox2.Items.AddRange(month)

        For i As Integer = 2010 To Integer.Parse(Now.Date.Year.ToString)
            ComboBox3.Items.Add(i)
        Next

        ComboBox3.Text = Now.Date.Year.ToString
        ComboBox3.DropDownStyle = ComboBoxStyle.DropDown
        ComboBox3.AutoCompleteMode = AutoCompleteMode.SuggestAppend
        ComboBox3.AutoCompleteSource = AutoCompleteSource.ListItems

        ComboBox2.Text = Now.Date.Month.ToString("00")
        ComboBox2.DropDownStyle = ComboBoxStyle.DropDown
        ComboBox2.AutoCompleteMode = AutoCompleteMode.SuggestAppend
        ComboBox2.AutoCompleteSource = AutoCompleteSource.ListItems

        ComboBox1.SelectedIndex = 0

        Call Button1_Click(Me, Nothing)
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim salaryM As New Class_conn(ConnRegNfunction.connMode, _
                            ConnRegNfunction.連線字串Local, _
                            ConnRegNfunction.連線字串WebUri)
        Dim salaryDT = salaryM.DataTable("SELECT s.*,e.zhFname + e.zhName as 姓名,b.account FROM dbo.salaryM as s left join dbo.employee as e on s.staff_sn = e.staff_sn left join dbo.bank as b on s.staff_sn = b.staff_sn where s.ym = " & ComboBox3.Text.Trim & ComboBox2.Text.Trim & " and s.第幾次發薪 = " & TextBox1.Text.Trim & "", Nothing, Nothing)
        Dim rds As ReportDataSource = New ReportDataSource("yiTestDataSet_salaryM", salaryDT) 
        ReportViewer1.LocalReport.DataSources.Clear()
        ReportViewer1.LocalReport.DataSources.Add(rds)

        Dim rp1 As ReportParameter = _
        New ReportParameter("Report_Parameter_0", ComboBox3.Text.Trim)
        Dim rp2 As ReportParameter = _
        New ReportParameter("Report_Parameter_1", ComboBox2.Text.Trim)
        Dim rp3 As ReportParameter = _
        New ReportParameter("Report_Parameter_2", TextBox1.Text.Trim)

        ReportViewer1.LocalReport.SetParameters(New ReportParameter() {rp1})
        ReportViewer1.LocalReport.SetParameters(New ReportParameter() {rp2})
        ReportViewer1.LocalReport.SetParameters(New ReportParameter() {rp3})

  AddHandler ReportViewer1.Drillthrough, AddressOf DemoDrillthroughEventHandler

        ReportViewer1.RefreshReport()
        salaryM.Dispose()
    End Sub
End Class

CODE:使用報表事件 ReportViewer1_Drillthrough
Imports Microsoft.Reporting.WinForms
Public Class Printer_Salary
    Private orderDetailsData As DataTable = Nothing
    Function LoadOrderDetailsData(ByVal a As String) As DataTable
        Dim salaryM As New Class_conn(ConnRegNfunction.connMode, _
                            ConnRegNfunction.連線字串Local, _
                            ConnRegNfunction.連線字串WebUri)
        Dim salaryDT = salaryM.DataTable("SELECT s.*,e.zhFname + e.zhName as 姓名,b.account FROM dbo.salaryM as s left join dbo.employee as e on s.staff_sn = e.staff_sn left join dbo.bank as b on s.staff_sn = b.staff_sn where s.staff_sn = " & a & " and s.ym = " & ComboBox3.Text.Trim & ComboBox2.Text.Trim & " and s.第幾次發薪 = " & TextBox1.Text.Trim & "", Nothing, Nothing)
        salaryM.Dispose()
        Return salaryDT
    End Function

    Private Sub Printer_Salary_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.ReportViewer1.RefreshReport()
    End Sub

    Private Sub Printer_Salary_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown
        Me.FormBorderStyle = Windows.Forms.FormBorderStyle.FixedSingle
        Dim month() As String = {"01", "02", "03", "04", "05", "06", _
                                    "07", "08", "09", "10", "11", "12"}
        ComboBox2.Items.AddRange(month)

        For i As Integer = 2010 To Integer.Parse(Now.Date.Year.ToString)
            ComboBox3.Items.Add(i)
        Next

        ComboBox3.Text = Now.Date.Year.ToString
        ComboBox3.DropDownStyle = ComboBoxStyle.DropDown
        ComboBox3.AutoCompleteMode = AutoCompleteMode.SuggestAppend
        ComboBox3.AutoCompleteSource = AutoCompleteSource.ListItems

        ComboBox2.Text = Now.Date.Month.ToString("00")
        ComboBox2.DropDownStyle = ComboBoxStyle.DropDown
        ComboBox2.AutoCompleteMode = AutoCompleteMode.SuggestAppend
        ComboBox2.AutoCompleteSource = AutoCompleteSource.ListItems

        ComboBox1.SelectedIndex = 0
        Call Button1_Click(Me, Nothing)
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim salaryM As New Class_conn(ConnRegNfunction.connMode, _
                            ConnRegNfunction.連線字串Local, _
                            ConnRegNfunction.連線字串WebUri)
        Dim salaryDT = salaryM.DataTable("SELECT s.*,e.zhFname + e.zhName as 姓名,b.account FROM dbo.salaryM as s left join dbo.employee as e on s.staff_sn = e.staff_sn left join dbo.bank as b on s.staff_sn = b.staff_sn where s.ym = " & ComboBox3.Text.Trim & ComboBox2.Text.Trim & " and s.第幾次發薪 = " & TextBox1.Text.Trim & "", Nothing, Nothing)
        Dim rds As ReportDataSource = New ReportDataSource("yiTestDataSet_salaryM", salaryDT) 
        ReportViewer1.LocalReport.DataSources.Clear()
        ReportViewer1.LocalReport.DataSources.Add(rds)

        Dim rp1 As ReportParameter = _
        New ReportParameter("Report_Parameter_0", ComboBox3.Text.Trim)
        Dim rp2 As ReportParameter = _
        New ReportParameter("Report_Parameter_1", ComboBox2.Text.Trim)
        Dim rp3 As ReportParameter = _
        New ReportParameter("Report_Parameter_2", TextBox1.Text.Trim)

        ReportViewer1.LocalReport.SetParameters(New ReportParameter() {rp1})
        ReportViewer1.LocalReport.SetParameters(New ReportParameter() {rp2})
        ReportViewer1.LocalReport.SetParameters(New ReportParameter() {rp3})

        ReportViewer1.RefreshReport()
        salaryM.Dispose()
    End Sub

    Private Sub ReportViewer1_Drillthrough(ByVal sender As System.Object, ByVal e As Microsoft.Reporting.WinForms.DrillthroughEventArgs) Handles ReportViewer1.Drillthrough
        Dim myLocalReport As LocalReport
        myLocalReport = e.Report
        'If orderDetailsData Is Nothing Then'

        orderDetailsData = LoadOrderDetailsData(myLocalReport.GetParameters()("Report_Parameter_3").Values(0).Trim)

        'End If'
        myLocalReport.DataSources.Add(New ReportDataSource("yiTestDataSet_salaryM1", orderDetailsData))
    End Sub
End Class

步驟:
STEP1.
各自建立報表 report1.rdlc & report2.rdlc 及報表來源

注意:
報表來源不可以有沒使用到的數據來源
不然會一直出錯,沒有 DataSet_dt 數據來源



STEP2.
在父報表Report2設定
欄位導覽 跳至報表Report1 (所要鑽取的報表)
並設定要給予的參數(Report_Parameter_3 參數值 是此欄位的值)
(此參數在 Report1 及 Report2 參數名稱要相同)


範例畫面:
主(父)報表Report2


鑽取下的報表Report1


延伸:
若有多個欄位 鑽研不同的Report
則...
  Select Case e.ReportPath
   Case "Parent"
    Me.List_Customers_OrderTotalTableAdapter.Fill(Me.MyDataSet1.List_Customers_OrderTotal)
    RptrDS = New ReportDataSource("DataSet_1", Me.MyDataSet1.Tables("List_Customers_OrderTotal"))

   Case "Level1"
    Me.Show_OrderDetailsTableAdapter.Fill(Me.MyDataSet1.Show_OrderDetails, Integer.Parse(sParameter))
    RptrDS = New ReportDataSource("DataSet_2", Me.MyDataSet1.Tables("Show_OrderDetails"))

   Case "Level2"
    Me.Show_ProductsTableAdapter.Fill(Me.MyDataSet1.Show_Products, Integer.Parse(sParameter))
    RptrDS = New ReportDataSource("DataSet_3", Me.MyDataSet1.Tables("Show_Products"))

   Case Else
    Me.List_Customers_OrderTotalTableAdapter.Fill(Me.MyDataSet1.List_Customers_OrderTotal)
    RptrDS = New ReportDataSource("DataSet_1", Me.MyDataSet1.Tables("List_Customers_OrderTotal"))
  End Select


延伸:
若要多筆資料分頁
則...
Step1.將設計的Table(無資料列 只留表頭或表尾) 拉進 List裡


Step2.設定List屬性


顯示畫面:



自己想的報表:(應該滿多人會被這樣要求的, 不然紙張很浪費!!)
這一張報表剛好佔A4紙3分之1頁面
今天我想把三筆資料弄在同一張頁面

解決方式1:(很笨的方式)
查詢的資料結合,將每三筆資料結合成一組。
例如:

原始DataSet From DataBase
SN     名字     地址
1        陳         屏  
2        張         桃  
......
n        n           n             n


自定義DataSet, 每三筆組成一筆, 透過原始 DataSet 來組合
群組      row1     row2     row3     row4     row5     row6     row7     row8     row9
1           1            陳         屏         2           張         桃         3           x           x
2           4            x            x          5            x           x           6           x           x
......
n           n-2         x            x          n-1         x           x           n           x           x


同一個List,同樣的表格畫三個,並分別放入 row1~row9
第一個表格 row1~row3 第二個表格 row4~row6 第三個表格 row7~row9
分頁設定則是依 "群組" 來分頁


若資料剛好不足3筆成一個record時
則沒資料列的地方要補空白
不然格式會跑掉
而且畫出來的格式 如果有顏色
則必須再報表設計時 設定如果沒有值 得border為白色
(1.不知從程式有沒有辦法處理 報表的設定)
(2.不要用hiden 因為格式也會跑掉)
當然如果紙張不是白色的 就依那個顏色
(1.就嘿嘿嘿...囧 自己慢慢選顏色, 缺點...)

解決方法2:結尾的分頁符號不要勾選


顯示畫面:


注意:
A4紙直式輸出 會自動弄三頁
A4紙橫式輸出 會自動弄二頁
若要輸出為中一刀 寬21 長14
則報表上也要設計為中一刀格式
否則輸出依然是A4格式輸出
中一刀設定


參考:
Create Drill-Through Reports using ReportViewer in ASP.NET 2.0
ReportViewer教程(14)-钻取报表和传入参数
ReportViewer.Drillthrough 事件
使用RDLC报表(四)--钻取式报表
RDLC研取子报表
MSDN報表教學 - 加入鑽研報表
MSDN報表教學 - 第 5 課:加入傳遞至鑽研報表的參數
ReportViewer Control 相關的 Sample Code
如何控制reportviewer驅動RDLC一筆記錄呈現一頁

Reporting Services
Beginning SQL Server 2005 Reporting Services Part 1
Beginning SQL Server 2005 Reporting Services Part 2
Beginning SQL Server 2005 Reporting Services Part 3: The Chart Control
Beginning SQL Server Reporting Services Part 4

RDL(C) Report Design Step by Step 2: SubReport  <-- 這不是鑽研式報表
LocalReport.SubreportProcessing 事件 <-- 這不是鑽研式報表

ReportViewer SubReport 子報表

Difficulty setting ReportParameter

使用 PIVOT 和 UNPIVOT 讓資料多列變成一列
SQL - 使用 PIVOT
SQL資料轉行
續:SQL 資料轉行

待解決的設計: 思考一下別人的報表 如果是我要如何去設計...
請問該如何利用Report Viewer製作如內文所述報表?


2013年3月17日 星期日

[技巧] Using GetUpperBound(0) 取得儲存多筆Record的DataRow


Dim 病假() As DataRow = Me.MyCallForm.ds.Tables("attend").Select("type = '病假' and ym like '" & ComboBox1.Text & "%'")

For i As Integer = 0 To 病假.GetUpperBound(0)
    MsgBox(病假(i)("ym") + 病假(i)("type"))
Next

備註:
Dim 病假() As DataRow = Me.MyCallForm.ds.Tables("attend").Select("type = '病假' and ym like '" & ComboBox1.Text & "%' and substring(ym,6,2) <= " & Integer.Parse(ComboBox2.Text) & "")

ym欄位的資料型態為nchar
資料內容為六位數的 "月份日期" 組合
201003
201201
201202
201203
201302

可運用 substring() 來進行分割搜尋...
從條件來看 假設 ComboBox1.Text = 2012 , ComboBox2.Text = 02
則DataTable.Select()的filter結果為
201201
201202

參考:
DataTable.Select 方法 (String)
[C#] Datatable.Select 的運算式用法
C# [轉載] Datatable.Select 的運算式用法
DataTable.Select()中的表达式可使用的函数
dataTable 的處理
Convert DataRow Array to DataTable, DataTable Filter function DataTable.Select return DataTable
DataTable Select Function (datarow 轉為 datatable)

SQL函數 查詢SQL資料欄位相符的字串
MSSql 中Charindex ,Substring的使用
CHARINDEX (Transact-SQL)

2013年2月19日 星期二

[學習] 讓視窗保持在最上層


(一)
Dim frm備註 As New 詢價單備註編輯
frm備註.MyCallForm = Me
frm備註.ShowDialog()




(二)
此段程式碼是寫在同一個視窗(Form)

ShowDialog 的焦點會一直在被開啟的Form上
與之不同的是 Show 的焦點不會在開啟的Form上

所以當開啟時若要一直在焦點上的話
就必須在主視窗的Activated事件下寫段程式

又因為被開啟的Form 並不是MDI表單
所以必須在 Application.OpenForms 下去搜尋

在圖一的紅色框的範圍內連點兩下,則會使主視窗縮放
在紅色框外及黃色框外的範圍都無法點擊
雖然可點擊黃色框內的 button,但都是沒有反應的(ex:會更新主視窗的資料)
應該是因為 Activated 事件觸發後,其它事件(或反應)就會被攔截掉...(尚待解釋)
而 ShowDialog 則除本視窗外,其它視窗都無法點擊

Private Sub Button8_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button8.Click

     Dim frm As New 詢價單費用編輯
     'frm.TopMost = True
     'frm.Owner = Me.ParentForm
     'frm.Parent = Me.ParentForm
     'frm.Focus()
     'frm.Activate()
     frm.Show()
End Sub



Private Sub 詢價單資料輸入作業_Activated(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Activated
        For Each f As Form In Application.OpenForms
            If f.Text.Equals("詢價單費用編輯") Then
                f.Activate()
                Exit For
            End If
        Next
End Sub




(三)
若要讓視窗長駐最上層
則使用 TopMost = True
此時的可以點擊其它視窗
只是被開啟的視窗會一直長駐在最上層而己
即使使用者切換至其它應用程式



Private Sub Button8_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button8.Click

     Dim frm As New 詢價單費用編輯
     frm.TopMost = True
     'frm.Owner = Me.ParentForm
     'frm.Parent = Me.ParentForm
     'frm.Focus()
     'frm.Activate()
     frm.Show()
End Sub




而(一)及(二)
當使用者點選其它應用程式時,並不會顯示在最上層。



參考:
vb.net find form by title and edit control
VB.net視窗控制問題
利用SetWindowPos使表單永遠放到最上層!
如何在VB裡讓程式表單能夠最上層顯示
如何將 Form 顯示在最上層?
如何顯示其他Form卻又不讓其獲得Focus?
vb.net 轉移程式焦點
VB.Net Form關閉按鈕以及最上層顯示問題
請問如何讓開啟的form只在此視窗中最上層顯示
請問視窗最上層的問題
最上層FORM的鎖定
VB.Net Form顯示為最上層
當程式的前景被其他程式拿走時判斷並拿回前景
[C#]透過 SHDocVw 與 GetForegroundWindow 取得正在使用的 Internet Explorer 網址
[VB.NET]把.NET視窗嵌入.NET視窗或控制項

2013年1月10日 星期四

[學習] DataGridView 資料繫結 與 資料清除

資料顯示方式:
DataGridView1.DataSource = ds.Tables(0)

資料清除方式:
DataGridView1.DataSource = Nothing
DataGridView1.Refresh()

========================================
資料顯示方式:
For i As Integer = 0 To ds.Tables("family").Rows.Count - 1
     DataGridView2.Rows.Add(
          ds.Tables("family").Rows(i)(0),
          ds.Tables("family").Rows(i)(1),
          ds.Tables("family").Rows(i)(2),
          ds.Tables("family").Rows(i)(3),
          ds.Tables("family").Rows(i)(4))
Next

資料清除方式:
DataGridView2.Rows.Clear()

Error Msg:
無法清除這個清單

參考:
DataGridView全部删除不成功

2012年12月17日 星期一

[學習] 字串處理, 切割與截取

取得 "(" 起始位置 index
InStr(ComboBox1.Text, "(")

EX: 123(456)
從字串左邊第一個位置開始截取 直到位置 InStr(ComboBox1.Text, "(") - 1
Microsoft.VisualBasic.Left(ComboBox1.Text, InStr(ComboBox1.Text, "(") - 1)
Result : 123

Microsoft.VisualBasic.Right(cbo_發文者.Text, cbo_發文者.Text.Length-InStr(cbo_發文者.Text, "(")).ToString().Trim(")")
Result : 456

參考:
Functions (Visual Basic)
字串處理
常用VB字串處理函數
字串處理函數
Visual Basic 2005 - 善用 StringBuilder 提升字串處理效率
戰鬥吧!打工戰士!身為工程師須具備的字串處理思維!
在一個字串中插入另一個字串
[C#]簡單快速將各種數值字數轉成數字(string to int)
[隨手筆記]C#字串中的Right方法

[SQL] 判斷空白

select top 1 staff_sn from retainJob where staff_sn = e.staff_sn and endDate is null order by startDate DESC

參考:
MS SQL與Oracle判斷欄位是否為NULL的方法比較,COALESCE()、ISNULL()、NVL()
SQL COALESCE() Very Cool, But Slower Than ISNULL()
SQL - 使用 NULLIF
SQLServer 中的 ISNULL 和 NULLIF
SQL SERVER – Explanation and Comparison of NULLIF and ISNULL
ISNULL (Transact-SQL)
NULLIF (Transact-SQL)
SQL::CASE, NULLIF() and ISNULL()
Access中的IsNull()
在Access中,IsNull的作用僅僅是判斷是否為空值
不過Access還是有支援MS-SQL IsNull的相似指令碼,在Access是用 iif 替代..
Select iif(IsNull( express ), value1, value2 ) From TableName
語法說明,判斷express是否為空,若是空的回傳value1,反之則回傳value2

[學習] 限制上傳的副檔名

Private Sub Button12_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button12.Click

     Dim f As OpenFileDialog = New OpenFileDialog()
     f.Filter = "文件格式(*.pdf;*.doc;*.docx;*.ppt;*.pptx;*.xls;*.xlsx)|*.pdf;*.doc;*.docx;*.ppt;*.pptx;*.xls;*.xlsx"  '支援格式   'WMF   'ICO
     'f.Filter = "All   Image   Formats   (*.bmp;*.jpg;*.jpeg;*.gif;*.png;*.tif)| " & _
     '   "*.bmp;*.jpg;*.jpeg;*.gif;*.png;*.tif|Bitmaps   (*.bmp)|*.bmp| " & _
     '   "GIFs   (*.gif)|*.gif|JPEGs   (*.jpg)|*.jpg;*.jpeg|PNGs   (*.png)|*.png|TIFs   (*.tif)|*.tif|All   Files   (*.*)|*.* "

     f.FilterIndex = 1
     f.ShowDialog(Me)
     Me.txbPath.Text = f.FileName

     If Path.GetExtension(txbPath.Text.Trim) = ".pdf" OrElse Path.GetExtension(txbPath.Text.Trim) = ".doc" OrElse Path.GetExtension(txbPath.Text.Trim) = ".docx" OrElse Path.GetExtension(txbPath.Text.Trim) = ".ppt" OrElse Path.GetExtension(txbPath.Text.Trim) = ".pptx" OrElse Path.GetExtension(txbPath.Text.Trim) = ".xls" OrElse Path.GetExtension(txbPath.Text.Trim) = ".xlsx" Then
     'do nothing
     Else
          If txbPath.Text.Trim <> "" Then
               MsgBox("僅 圖片格式(*.pdf;*.doc;*.docx;*.ppt;*.pptx;*.xls;*.xlsx) 可上傳!!")
          End If
          Exit Sub
     End If

'限制檔案大小

'檔圖片轉檔 並縮圖 - 以減少儲存空間

     'MsgBox(Path.GetFileName(f.FileName)) 取得檔案名稱(含副檔名)
     'Path.GetExtension 取得副檔名
     'Me.PictureBox1.ImageLocation = Me.txbPath.Text '取得完整路徑
End Sub

Note:
除了前端判斷
後端也要判斷
小心偽裝的檔案


參考:
VS 2008
.Net 3.5

~~要如何限制上傳的副檔名~~
如何限制FileUpload的副檔名
怎么限制上传图片的格式和大小? - [Asp.net]
上傳檔案時,限制只能pdf、xls的副檔名
OpenFileDialog 元件常用屬性和方法
Path.GetExtension 方法
Path.GetExtension 获取扩展名
[ASP.NET]將上傳圖檔分成大小圖後存入資料庫
Use With statement with OpenFileDialog

[SQL] 多欄位查詢結果合併成一個字串

同個Row的兩個欄位(或N個欄位) 使用+ 來連接成一個欄位!

sqlQuery1:
SELECT (e.zhFname+e.zhName) as zhName,(e.enName+'  '+e.enFname) as enName FROM table

顯示結果:
zhName = "志玲"
enName = "LiYin Lin"

sqlQuery2:
SELECT (convert(nvarchar(4),系統ID) + '(' + 系統名稱 + ')') as 系統 FROM [Usys系統別資料表] WHERE 系統ID <> 0

顯示結果:
系統 = 1(內銷業務管理)

Note:
若有某一欄位型態不是字串(EX:integer ,double, etc... 日期沒試過~)
就必須 (convert(nvarchar(10),系統ID) 轉成字串

假設原本資料庫設定為 int(4) 其可表示範圍為
 - 2,147,483,647 ~ 2,147,483,647 
0~4,294,967,295 兩者皆為10位數

故轉字串時 就必須設 nvarchar(10) OR varchar(10)
否則會產生溢位錯誤...

參考:
select firstname+lastname from tb1;
用  +  做連接
+ (字串串連) (Transact-SQL)
CONCAT( ) 的語法
SQL Server 2012 :認識 CONCAT 字串函數

M$ sqlserver 2005
SQL 語法如何將多欄位查詢結果合併成一個字串
如何將多行查詢結果合併成單一字串?
SQL指令— CONCAT(字符串连接函数)
SQL 合并字段、拼字段、把多个数值拼写成一个字段。

===================================================
不同ROW的同一個欄位運用 FOR XML PATH 來連接成一個欄位!

資料結構:

語法 FOR XML PATH 之後的資料:

  select [pro] from yiTest.dbo.person for xml path('');

  select [pro]+',' from yiTest .dbo.person for xml path('');

  SELECT
  (
  (SELECT ','+[pro]
  FROM [yiTest].[dbo].[person] t2
  --WHERE t2.id = t1.id
  FOR XML PATH('')
  )
  )as [pro]
  FROM
  [yiTest].[dbo].[person] t1

    SELECT
  (
  (SELECT ','+[pro]
  FROM [yiTest].[dbo].[person] t2
  WHERE t2.id = t1.id
  FOR XML PATH('')
  )
  )as [pro]
  FROM
  [yiTest].[dbo].[person] t1

  select id,name,
  (select ','+pro from yiTest .dbo.person t1 where t1.id = t2.id for xml path('')) pro
  from yiTest.dbo.person t2
  group by id,name

參考:
SQL SERVER 2005 以後才支援 FOR XML PATH
SQL SERVER 2012 以後微軟提供了 CONCAT函數 來實現此功能
Concatenate the values in a column in SQL Server 2000 and 2005
使用 PATH 模式
一秒看破 T - SQL 多筆欄位合併
SQL 合并多条记录为一条
[SQL]將多筆資料合併為一筆顯示(FOR XML PATH)
[SQL]將多筆資料同一欄位值合併
[SQL] 多筆資料合併為一筆
灵活运用 SQL SERVER FOR XML PATH
SQL Server 2005 “FOR XML PATH” Multiple tags with same name
[MS SQL]將多筆資料合併欄位,減少不必要的連線
將多筆相同鍵值的欄位內容合併
T-SQL多筆輸出資料合併單一欄位輸出
使用 MSSQL 打造仿 MySQL 的group_concat 函数的山寨版
SQL語法如何將直的資料做橫向的字串連結
mssql2005如何实现类似GROUP_CONCAT (my-sql) 的功能
GROUP_CONCAT In MS-SQL
Simulating group_concat MySQL function in Microsoft SQL Server 2005?
Emulating MySQL’s GROUP_CONCAT() Function in SQL Server 2005

FOR XML PATH 多筆資料合併為一筆
FOR XML PATH 多筆資料合併為一筆

其它參考:
動態將多筆資料的特定欄位依分隔符號組成字串
[SQL]利用UNION ALL整合統計合併資料
[Oracle]請問如果查詢條件無資料能否顯示筆數為 0 呢?
SQL不同TABLE相同欄位合併的方法
MS SQL多表查詢合併
SQL合併查詢?(超難)
[Oracle]多筆資料合併在同一列上
SQL2005/2008手工注入之批量爆数据for xml path

使用 PIVOT 和 UNPIVOT 讓資料多列變成一列
SQL - 使用 PIVOT
動態 PIVOT 陳述式:Dynamic PIVOT
SQL資料轉行
續:SQL 資料轉行

SQL SERVER 2000/2005 列转行 行转列

2012年12月14日 星期五

[除錯] 字串或二進位資料會被截斷


資料庫insert時,Error Msg:
1.字串或二進位資料會被截斷
2.數值對 Int32 而言太大或太小


資料庫欄位型態:
int(4)


解決程式:
'不能用CInt 因為超過最大值 會無法判斷 (因為無法轉成INT)
If CDec(C.Text.Trim) > 2147483647 Then
MsgBox("資料欄位不准許大於[2147483647]!!")
End If


參考:
字串或二进位资料会被截断。
如何快速得知"字串或二進位資料會被截斷"是哪個欄位長度不足??
字串或二進位資料會被截斷

2012年12月7日 星期五

[學習] 取得系統環境路徑 Fonts 並且判斷系統字型是否存在

問題:
得知應用程式所安裝的系統OS(Win32)下~
系統字型是否存在著型某種字型~

解決:
Imports System.IO
        '取得環境路徑 fonts 系統字型資料夾
        '.NET Framweork 4 版本之後 才有 fonts
        'Dim strAns As String = Environment.GetFolderPath(Environment.SpecialFolder.fonts)

        ' get parent of System folder to have Windows folder
        Dim dirWinFolder As DirectoryInfo = Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.System))
        'DirectoryInfo dirWindowsFolder = Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.System));

        ' Concatenate Fonts folder onto Windows folder.
        Dim strFontsFolder As String = Path.Combine(dirWinFolder.FullName, "Fonts")
        'string strFontsFolder = Path.Combine(dirWindowsFolder.FullName, "Fonts");

        'Results in full path e.g. "C:\Windows\Fonts"
        'MsgBox(dirWinFolder.Parent.Name) 'C:\
        'MsgBox(dirWinFolder.Name) 'Windows
        'MsgBox(strFontsFolder) 'C:\Windows\Fonts

        '判斷是否存在字型
        Dim strFullPath As String = strFontsFolder & "\dftt-b5.ttf"
        If File.Exists(strFullPath) Then
            'MsgBox("存在!")
        Else
            File.Copy(Application.StartupPath & "\dftt-b5.ttf", strFullPath)
        End If

備註:
因為系統載入後,當系統無應用程式所使用字型時。
即使將字型COPY到系統字型資料夾,應用程式依然是使用預設字型。
因為應用程式字型設定在於COPY之前。

第二次開始應用程式,程式才會真正LOAD到 dftt-b5.tff 字型檔。

解決辦法:
(1)在程式中解決? 如何在應用程式設置字型之前COPY到系統字型資料夾?
(2)將字型檔直接包在應用程式安裝檔,並指定字型安裝路徑為系統字型資料夾路徑。
    那路徑設定怎麼設定?
(3)解決(1)辦法...(不是很好的辦法)
    在COPY完成後,將所有使用到此字型的控制項 or others...
    其字型指為 dftt-b5.tff,還沒試,應該可行一 一?

參考:
VS 2008
.Net 3.5
Environment.GetFolderPath Method (Environment.SpecialFolder)
How to get the path to the Windows fonts folder?
How to get the path to the Windows fonts folder?
Finding Font Filename from Font Title
Font Installation (copying file into Fonts directory from server to user's machine)
copy a font file in my programm resources to windows fonts
How do I install a font on a user's machine in VB.NET so applications like Word can use it?
VB.NET修改host文件
获取ALL USER 的特殊目录的类
如何获取系统下字体的路径?
如何判断使用者电脑中系统字型大小?
查知目前系統字型大小?
抓系統字型設定問題
取得電腦內部所有安裝字型
程式的啟動與載入
c# 獲取相對路徑
取得目前執行程式的目錄

2012年11月27日 星期二

[技巧] ReportViewer 超連結 Hyperlink 開啟本機檔案

Get Selected Value From ReportViewer via Hyperlink

CrystalReport 可直接在公式呼叫外部程式並傳入參數 或 直接開啟檔案 PDF WORD,etc...
formula = "C:\DAYLIGO\TEST\DayActivateFormWinApp.exe 21 " & LEFT(CSTR({RY010採購合同資料表.批號}),1)  & ""

ReportViewer 無法直接在公式呼叫外部程式 或 開啟檔案 PDF WORD,etc...
僅能超連結URL的網頁,所連結網頁會 GET/POST 接收參數!

或許 ReportViewer 有這樣的功能也說不定... 網路上也找的到相關的需求,但沒有解答!

解決方法:
    Private Sub ReportViewer1_Hyperlink(ByVal sender As System.Object, ByVal e As Microsoft.Reporting.WinForms.HyperlinkEventArgs) Handles ReportViewer1.Hyperlink
        '法一
        Dim aa As String = e.Hyperlink
        aa = aa.Replace("http://", "")
        aa = aa.Replace("/", " ")
        Shell("C:\Dayligo\TEST\DayActivateFormWinApp.exe " & aa, AppWinStyle.NormalFocus)
        'MsgBox(e.Hyperlink)
        e.Cancel = True

        '法二

        Dim bb As String = e.Hyperlink
        bb = bb.Replace("%20", " ")
        bb = bb.Replace("file:///", "")
        'MsgBox(e.Hyperlink)
        'MsgBox(bb)
        Shell(bb, AppWinStyle.NormalFocus)

        e.Cancel = True
    End Sub

'法一
在 report1.rdlc 將表格設定導覽,並指定到URL   ="http://19/" & Fields!sdid.Value
在 reporviewer1 運用 Hyperlink 事件,並取出 link 參數。
並在程式中解析~ 取出所要的參數。
19表示我要呼叫哪支程式(表單Form) 並傳入參數 sdid.Value

注意:
設定 enablehyperlinks = true
http:// <-- 這樣不會觸發連結事件
http://1/ <-- 這樣才會觸發連結事件



'法二
跳至URL:
="C:\Dayligo\TEST\DayActivateFormWinApp.exe 19 " & Fields!sdid.Value

開發工具:
VS2008
Framework3.5

參考:
如何获取ReportViewer呈现的报表中某单元格的值?
'Jump To' action with relative hyperlink
Hyperlink to a local file doesn't work
在ReportViewer中使用超链接(HyperLink)
啟動應用程式並且傳入參數

備註:
A組件下,某個視窗(水晶報表)
透過報表某欄位hyperlink開啟本地檔案DayActivateFormWinApp.exe (並且傳參數給本地檔案)
透過DayActivateFormWinApp.exe及接收的參數,再來呼叫A組件下的某支副程式
透過此支程式來呼叫B組件下,某個視窗(EX:個人資料檔案!!)
B組件依接到的參數顯示資料

2012年11月26日 星期一

[技巧] 判斷是否已開啟視窗

法一 - A、
只能在 父MDI [MAIN_ligoHRsys] 下運作! 當嵌入其它組件時,無法在其下 父MDI 下運算!
        '若表單已存在 則讓他為主要顯示表單
        If l_Frm IsNot Nothing Then

            For i As Integer = 0 To MAIN_ligoHRsys.FindForm().MdiChildren.Length - 1
                If frmText.Equals(MAIN_ligoHRsys.FindForm().MdiChildren(i).Text) Then
                    MAIN_ligoHRsys.FindForm().MdiChildren(i).Tag = 4
                    MAIN_ligoHRsys.FindForm().MdiChildren(i).Activate()
                    DirectCast(MAIN_ligoHRsys.FindForm().MdiChildren(i), Object).MyDataRequery(Nothing)
                End If
            Next
        End If


法一 - B、
當嵌入在任何組件時 在其 父MDI 下運作,必使用 Me.Parent 方可執行!
        '若表單已存在 則讓他為主要顯示表單
        If l_Frm IsNot Nothing Then

            For i As Integer = 0 To Me.Parent.FindForm().MdiChildren.Length - 1
                If frmText.Equals(Me.Parent.FindForm.MdiChildren(i).Text) Then
                    Me.Parent.FindForm.MdiChildren(i).Activate()
                    Me.Parent.FindForm.MdiChildren(i).Tag = 1
                    DirectCast(Me.Parent.FindForm().MdiChildren(i), Object).MyDataRequery(Nothing)
                End If
            Next
        End If


法二、
If My.Application.OpenForms.Item("FormName") IsNot Nothing Then
     'do something here 已經打開
Else
     'do something here 還沒打開
End If


法三、[C#]
            if (Application.OpenForms.OfType<frm力高裝箱明細列印作業>().Count() == 1)
                Application.OpenForms.OfType<frm力高裝箱明細列印作業>().First().Activate();
            else
            {
                frm裝箱明細列印作業 frm = new frm裝箱明細列印作業();
                frm.MdiParent = this.MdiParent;
                frm.Show();
            }   


參考:
[MSDN]Form.ActiveMdiChild 屬性
[MSDN]My.Application.OpenForms 屬性
VB.NET判断一个窗口是否打开的代码
[C#.NET] 如何 使用 WinForm 關閉 視窗 事件
C# WinForm 只允许运行一个实例 ,如果有就激活到前段
WinFrom 判断窗体是否已存在

2012年11月18日 星期日

[除錯] 轉換 expression 到資料型別 smalldatetime 時發生算術溢位錯誤


---Error Message----
1.INSERT INTO SQL SERVER時引發錯誤,SQL資料類型 smalldatetime
將 varchar 資料類型轉換成 smalldatetime 資料類型時,產生超出範圍的值

2.
轉換 expression 到資料型別 smalldatetime 時發生算術溢位錯誤
轉換 nvarchar 到資料型別 smalldatetime 時發生算術溢位錯誤
,etc...




資料庫欄位型態為 datetime or smalldatetime
程式 insert 時,必須注意日期規則是否溢位

Ex:
一月份最大日期為31日
此時 insert 32 便會 error


解決辦法(1)--  
其實用 ISDate() 最準 
接受輸入格式 
(1)12-24 (自動加入今年)
(2)12-01-01 ,  2013-1-1,
(3)2011/1/1 ,  2012/01/12
(4)12/1-01 


在 insert 前判別規則
ex: 正規化表示法
If Not Regex.IsMatch(C.Text.Trim, "^((19|20)?[0-9]{2}[- /.](0?[1-9]|1[012])[- /.](0?[1-9]|[12][0-9]|3[01]))*$") Then
   'do something
End



解決辦法(2)--
將資料庫 欄位型態 改為 varchar / nvarchar


溢位是因為期中有NULL值或空白值 

解決辦法(3)--
WHERE下條件
where date <> "" and date is not null 或是 where isdate(date)

NOTE:
一、IsDate() 有效日期的範圍是介於西元 100 年 1 月 1 日與西元 9999 年 12 月 31 日之間;其有效範圍會因作業系統而有所差異。

二、
smalldatetime 有效時間範圍 1900/1/1~2079/6/6
datetime 有效時間範圍 1753/1/1~9999/12/31
所以如果不用到太遠的日期範圍,就會使用smalldatetime。
更關鍵的差別,smalldatetime只精準到分,而datetime可精準到3.33毫秒。





參考1
參考2
參考3




[學習] Directory.GetCurrentDirectory 和 Application.StartupPath 區別

Imports System.IO

—————————————————————————————
StartupPath 程式執行後,路徑位置不因外在因素而變。
GetCurrentDirectory 程式執行後,路徑位置會因外在因素而變。
—————————————————————————————

獲取文件路徑定義
Application.StartupPath——獲取啟動了應用程序的可執行文件的路徑,不包括可執行文件的名稱。
Environment.CurrentDirectory——獲取和設置當前目錄(即該進程從中啟動的目錄)的完全限定路徑。
Application.ExecutablePath——獲取啟動了應用程序的可執行文件的路徑,包括可執行文件的名稱。
Directory.GetCurrentDirectory()——獲取應用程序的當前工作目錄。
Directory.GetCurrentDirectory()——程序文件自身的路徑。


GetCurrentDirectory 會受 OpenFileDialog(SaveFileDialog) 的影響,而改變路徑位置。
假如有兩個程式 C:/A/a.exe 和 C:/B/b.exe
當在 a.exe 中啟動 b.exe,System.Diagnostics.Process.Start(@"C:/B/b.exe")
此時 b.exe 中的 Directory.GetCurrentDirectory() 返回值為 “C:/A”
Application.StartupPath 值為“C:/B”

如果直接在 C:/B/ 中啟動 b.exe,那麼兩個值就會一樣,都為“C:/B”
這就是 Directory.GetCurrentDirectory 和 Application.StartupPath 的區別

Application.StartupPath 是程序的啟動目錄,這個在程序運行以後,就不會改變了。
Directory.GetCurrentDirectory() 是"當前目錄",是可以在程序運行時候改變的 ,
用Directory.SetCurrentDirectory() 就可以改變。
Directory.GetCurrentDirectory() 初始值和 Application.StartupPath() 一樣。

參考:
[C#]使用 Path 類別取得檔案或目錄路徑資訊
File.Exists 方法
有关File.Exists(filename)的问题
c# 獲取相對路徑
取得目前執行程式的目錄

2012年11月13日 星期二

[除錯] 建立視窗控制代碼時發生錯誤 (下)

建立視窗控制代碼時發生錯誤 (上)

網路上這樣的發問訊息不多...
在(中文)資訊很少 也無解決方法...
有談論到的中文網站
 點我點我(1)
 點我點我(2) <<---- 有解決方法 但不是我要的!

(英文)資訊較多 卻苦無解決方法(讀者可以試試找英文的文件)...
[KeyWords]
Creating Window Handle
System.outOfMemoryException
System.NullReferenceException
MdiParent
FormWindowState.Maximized

有遇到相同原因的 或許可以試試
若剛好同樣的原因 那恭喜你 可以解決了

解決辦法

(1)

        p_mdi.MdiParent = Me
        p_mdi.WindowState = FormWindowState.Maximized
        p_mdi.Show()

改成
        p_mdi.Owner = Me
        p_mdi.WindowState = FormWindowState.Maximized
        p_mdi.Show()

這樣就不是MDI表單了~
但問題解決了~

(2)

p_mdi.WindowState = FormWindowState.Maximized

註解掉~ 並且不讓子表單在放大狀態運作~
這樣在畫面上會很怪 也很不符合使用邏輯~
但問題也解決了~

實際上可解決辦法

(1)
(Coding狀態) 將 [UI畫面] 拉大至可以將 [TextBox1] 容納~

(2)
將 btn[版面設置] 移至 [TextBox1] 後面~ 此時(Coding狀態) [TextBox1] 便落在 [UI畫面] 上~

(3)
將 [TextBox1] 位置 調置前面 使落在 [UI畫面] 上~

(4)
不管你用什麼辦法~ 
(刪除前面某個btn or others 讓 [TextBox1] 落在 [UI畫面] 上)
(刪除 [TextBox1])
, etc...

只要讓 [TextBox1] 在(Coding狀態) [UI畫面上] 便解決問題!
若是在程式執行時~ 才拉大UI畫面 一樣會出錯!


真正原因在於...............................................(研究中)

一、
我將專案每個表單內的程式全清空~ 僅保留空的程式!

EX: (表單 Class 原始)
Public Class MGMT_Personal
       'do something
End Class

UI設計畫面保留~
程式依然出錯~ 所以確定不是 Code 的問題!

二、
建立新的專案 測試MDI 也將 [TextBox1] (Codeing狀態)移出 [UI畫面] 外~
執行不會出錯 所以是原本專案上 拉UI時 未知的地方出錯~



----不無可能是程式碼某部份寫錯 for loop 之類的東西----

[除錯] 建立視窗控制代碼時發生錯誤 (上)

建立視窗控制代碼時發生錯誤 (下)

(1)開發環境 Development Environment
WinXP (32-bit x86) SP3
VS.NET 2008
.Net Framework 3.5

VB WinForm
MDI Form

(2)程式碼 Code
    '建立新的子表單
    Private Sub ShowMDIForm(ByVal p_mdi As Form)
        p_mdi.MdiParent = Me
        'p_mdi.Owner = Me
        p_mdi.WindowState = FormWindowState.Maximized
        p_mdi.Show()
    End Sub

    '檢查是否子表單已存在
    Function checkFormExist(ByVal FormText As String) As Boolean
        Dim bFound As Boolean = False
        For Each f As Form In Me.MdiChildren
            If f.Text.Equals(FormText) Then
                f.Activate()
                bFound = True
                Exit For
            End If
        Next
        Return bFound
    End Function

    '建立子表單
    Private Sub TreeView1_NodeMouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeNodeMouseClickEventArgs) Handles TreeView1.NodeMouseClick
        Dim l_Frm As Form = New Form
        Select Case e.Node.Text
            Case "個資管理"
                l_Frm = New MGMT_Personal
            Case "薪資管理"
                l_Frm = New MGMT_Salary
            Case "任職管理"
                l_Frm = New MGMT_P
            Case "事項管理"
                l_Frm = New MGMT_ImptItem
        End Select

        '判斷存表單是否已存在 - 若否則開啟 New & Show
        If checkFormExist(l_Frm.Text) = False Then
            ShowMDIForm(l_Frm)
        End If

        '判斷存表單是否已存在 - 若是則開啟 Activate
        If l_Frm IsNot Nothing Then
            For i As Integer = 0 To Me.MdiChildren.Length - 1
                If e.Node.Text.Equals(Me.MdiChildren(i).Text) Then
                    Me.MdiChildren(i).Activate()
                    'Return
                End If
            Next
        End If
    End Sub

(3)參考畫面


(4)錯誤產生時間
當點選 "任職管理" 再點選其它 "表單選項" 便會發生 Error!

(5)參考辦法
疑難排解例外狀況:System.OutOfMemoryException


使用過多的 Managed 記憶體,通常是因為:
  • 將大量資料集讀入記憶體中。
  • 建立過多的快取項目。
  • 上傳或下載大型檔案。
  • 剖析檔案時,使用太多規則運算式 (Regular Expression) 或字串。
  • 檢視狀態過多。
  • 工作階段狀態中有過多資料,或工作階段過多。
在 COM 物件上叫用方法,而且這個 COM 物件會傳回包含安全陣列 (非固定大小的陣列) 的使用者定義型別時,便可能會擲回這個例外狀況,其中的訊息為:「存放裝置空間不足,無法完成此操作」。這是因為 .NET Framework 無法封送處理具有安全陣列型別的結構欄位。

(6)錯誤訊息
System.OutOfMemoryException 未處理
  Message="建立視窗控制代碼時發生錯誤。"
  Source="System.Windows.Forms"
  StackTrace:
       於 System.Windows.Forms.NativeWindow.CreateHandle(CreateParams cp)    於 System.Windows.Forms.Control.CreateHandle()    於 System.Windows.Forms.Form.CreateHandle()    於 System.Windows.Forms.Control.get_Handle()    於 System.Windows.Forms.Form.SetVisibleCore(Boolean value)    於 System.Windows.Forms.Control.Show()    於 eHRsys.MAIN_ligoHRsys.ShowMDIForm(Form p_mdi) 於 C:\Documents and Settings\Administrator\My Documents\Visual Studio 2008\eHRsys\eHRsys\MAIN_ligoHRsys.vb: 行 33    於 eHRsys.MAIN_ligoHRsys.TreeView1_NodeMouseClick(Object sender, TreeNodeMouseClickEventArgs e) 於 C:\Documents and Settings\Administrator\My Documents\Visual Studio 2008\eHRsys\eHRsys\MAIN_ligoHRsys.vb: 行 74    於 System.Windows.Forms.TreeView.OnNodeMouseClick(TreeNodeMouseClickEventArgs e)    於 System.Windows.Forms.TreeView.WmNotify(Message& m)    於 System.Windows.Forms.TreeView.WndProc(Message& m)    於 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)    於 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)    於 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)    於 System.Windows.Forms.UnsafeNativeMethods.SendMessage(HandleRef hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)    於 System.Windows.Forms.Control.SendMessage(Int32 msg, IntPtr wparam, IntPtr lparam)    於 System.Windows.Forms.Control.ReflectMessageInternal(IntPtr hWnd, Message& m)    於 System.Windows.Forms.Control.WmNotify(Message& m)    於 System.Windows.Forms.Control.WndProc(Message& m)    於 System.Windows.Forms.ScrollableControl.WndProc(Message& m)    於 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)    於 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)    於 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)    於 System.Windows.Forms.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)    於 System.Windows.Forms.NativeWindow.DefWndProc(Message& m)    於 System.Windows.Forms.Control.DefWndProc(Message& m)    於 System.Windows.Forms.TreeView.WmMouseDown(Message& m, MouseButtons button, Int32 clicks)    於 System.Windows.Forms.TreeView.WndProc(Message& m)    於 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)    於 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)    於 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)    於 System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)    於 System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)    於 System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)    於 System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)    於 System.Windows.Forms.Application.Run(ApplicationContext context)    於 Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()    於 Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()    於 Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)    於 eHRsys.My.MyApplication.Main(String[] Args) 於 17d14f5c-a337-4978-8281-53493378c1071.vb: 行 81    於 System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)    於 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)    於 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()    於 System.Threading.ThreadHelper.ThreadStart_Context(Object state)    於 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)    於 System.Threading.ThreadHelper.ThreadStart()
  InnerException: System.NullReferenceException
       Message="並未將物件參考設定為物件的執行個體"
       Source="System.Windows.Forms"
       StackTrace:
            於 System.Windows.Forms.NativeWindow.WindowClass.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)    於 System.Windows.Forms.UnsafeNativeMethods.IntCreateWindowEx(Int32 dwExStyle, String lpszClassName, String lpszWindowName, Int32 style, Int32 x, Int32 y, Int32 width, Int32 height, HandleRef hWndParent, HandleRef hMenu, HandleRef hInst, Object pvParam)    於 System.Windows.Forms.UnsafeNativeMethods.CreateWindowEx(Int32 dwExStyle, String lpszClassName, String lpszWindowName, Int32 style, Int32 x, Int32 y, Int32 width, Int32 height, HandleRef hWndParent, HandleRef hMenu, HandleRef hInst, Object pvParam)    於 System.Windows.Forms.NativeWindow.CreateHandle(CreateParams cp)
       InnerException:

-------------------------------------------------------------------------

如需叫用 Just-In-Time (JIT) 偵錯的詳細資料,
請參閱本訊息結尾處 (而非這個對話方塊) 的資訊。

************** 例外狀況文字 **************
System.OutOfMemoryException: 建立視窗控制代碼時發生錯誤。 ---> System.NullReferenceException: 並未將物件參考設定為物件的執行個體
   於 System.Windows.Forms.NativeWindow.WindowClass.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
   於 System.Windows.Forms.UnsafeNativeMethods.IntCreateWindowEx(Int32 dwExStyle, String lpszClassName, String lpszWindowName, Int32 style, Int32 x, Int32 y, Int32 width, Int32 height, HandleRef hWndParent, HandleRef hMenu, HandleRef hInst, Object pvParam)
   於 System.Windows.Forms.UnsafeNativeMethods.CreateWindowEx(Int32 dwExStyle, String lpszClassName, String lpszWindowName, Int32 style, Int32 x, Int32 y, Int32 width, Int32 height, HandleRef hWndParent, HandleRef hMenu, HandleRef hInst, Object pvParam)
   於 System.Windows.Forms.NativeWindow.CreateHandle(CreateParams cp)
   --- 內部例外狀況堆疊追蹤的結尾 ---
   於 System.Windows.Forms.NativeWindow.CreateHandle(CreateParams cp)
   於 System.Windows.Forms.Control.CreateHandle()
   於 System.Windows.Forms.Form.CreateHandle()
   於 System.Windows.Forms.Control.get_Handle()
   於 System.Windows.Forms.Form.SetVisibleCore(Boolean value)
   於 System.Windows.Forms.Control.Show()
   於 eHRsys.MAIN_ligoHRsys.ShowMDIForm(Form p_mdi) 於 C:\Documents and Settings\Administrator\My Documents\Visual Studio 2008\Projects\eHRsys\eHRsys\MAIN_ligoHRsys.vb: 行 9
   於 eHRsys.MAIN_ligoHRsys.TreeView1_NodeMouseClick(Object sender, TreeNodeMouseClickEventArgs e) 於 C:\Documents and Settings\Administrator\My Documents\Visual Studio 2008\Projects\eHRsys\eHRsys\MAIN_ligoHRsys.vb: 行 55
   於 System.Windows.Forms.TreeView.OnNodeMouseClick(TreeNodeMouseClickEventArgs e)
   於 System.Windows.Forms.TreeView.WmNotify(Message& m)
   於 System.Windows.Forms.TreeView.WndProc(Message& m)
   於 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   於 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   於 System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)


************** 已載入的組件 **************
mscorlib
    組件版本: 2.0.0.0
    Win32 版本: 2.0.50727.3634 (GDR.050727-3600)
    程式碼基底: file:///C:/WINNT/Microsoft.NET/Framework/v2.0.50727/mscorlib.dll
----------------------------------------
eHRsys
    組件版本: 1.0.0.0
    Win32 版本: 1.0.0.0
    程式碼基底: file:///C:/Documents%20and%20Settings/Administrator/My%20Documents/Visual%20Studio%202008/Projects/eHRsys/eHRsys/bin/Debug/eHRsys.exe
----------------------------------------
Microsoft.VisualBasic
    組件版本: 8.0.0.0
    Win32 版本: 8.0.50727.3053 (netfxsp.050727-3000)
    程式碼基底: file:///C:/WINNT/assembly/GAC_MSIL/Microsoft.VisualBasic/8.0.0.0__b03f5f7f11d50a3a/Microsoft.VisualBasic.dll
----------------------------------------
System
    組件版本: 2.0.0.0
    Win32 版本: 2.0.50727.3634 (GDR.050727-3600)
    程式碼基底: file:///C:/WINNT/assembly/GAC_MSIL/System/2.0.0.0__b77a5c561934e089/System.dll
----------------------------------------
System.Windows.Forms
    組件版本: 2.0.0.0
    Win32 版本: 2.0.50727.3637 (GDR.050727-3600)
    程式碼基底: file:///C:/WINNT/assembly/GAC_MSIL/System.Windows.Forms/2.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
----------------------------------------
System.Drawing
    組件版本: 2.0.0.0
    Win32 版本: 2.0.50727.3639 (GDR.050727-3600)
    程式碼基底: file:///C:/WINNT/assembly/GAC_MSIL/System.Drawing/2.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
----------------------------------------
System.Configuration
    組件版本: 2.0.0.0
    Win32 版本: 2.0.50727.3053 (netfxsp.050727-3000)
    程式碼基底: file:///C:/WINNT/assembly/GAC_MSIL/System.Configuration/2.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll
----------------------------------------
System.Xml
    組件版本: 2.0.0.0
    Win32 版本: 2.0.50727.3082 (QFE.050727-3000)
    程式碼基底: file:///C:/WINNT/assembly/GAC_MSIL/System.Xml/2.0.0.0__b77a5c561934e089/System.Xml.dll
----------------------------------------
System.Runtime.Remoting
    組件版本: 2.0.0.0
    Win32 版本: 2.0.50727.3053 (netfxsp.050727-3000)
    程式碼基底: file:///C:/WINNT/assembly/GAC_MSIL/System.Runtime.Remoting/2.0.0.0__b77a5c561934e089/System.Runtime.Remoting.dll
----------------------------------------
System.Windows.Forms.resources
    組件版本: 2.0.0.0
    Win32 版本: 2.0.50727.1433 (REDBITS.050727-1400)
    程式碼基底: file:///C:/WINNT/assembly/GAC_MSIL/System.Windows.Forms.resources/2.0.0.0_zh-CHT_b77a5c561934e089/System.Windows.Forms.resources.dll
----------------------------------------
mscorlib.resources
    組件版本: 2.0.0.0
    Win32 版本: 2.0.50727.3634 (GDR.050727-3600)
    程式碼基底: file:///C:/WINNT/Microsoft.NET/Framework/v2.0.50727/mscorlib.dll
----------------------------------------

************** JIT 偵錯 **************
若要啟用 Just-In-Time (JIT) 偵錯功能,則必須在
此應用程式或電腦的 .config 檔案中,設定
system.windows.forms 區段內的 jitDebugging 值。
且該應用程式也必須在啟用偵錯的狀態下進行
編譯。

例如:

<configuration>
    <system.windows.forms jitDebugging="true" />
</configuration>

當 JIT 偵錯功能啟用後,會將所有未處理的例外
狀況傳送給電腦上已註冊的 JIT 偵錯工具進行處
理,而不是使用這個對話方塊來處理。

2012年11月9日 星期五

[學習] If Else 判斷式 細節注意~

AndAlso運算子


問題(Problem):
從資料庫撈資料時~
若某資料型態為日期(or 其它特殊型態)時~
用 Foor-loop or while-loop 取得資料列(並顯示在畫面上)~
用以下的 If判斷式 會出錯~

答案(Answer):
因為 If 判斷式~ 在判斷時會同時判斷 i是否符合條件 以及 arr(i + 1)是否符合條件~
故在此判斷式~ 便會出錯~
從字串 "XXXX" 至型別 'Date' 的轉換是無效的。

For i As Integer = 1 To 10
     If i = 3 And CDate(arr(i + 1)).ToShortDateString = "1900/1/1" Then
          C.Text = "尚無資料"
     End If
Next

需更改為
當判斷 i不符合時~ 就不會再判斷 arr(i + 1) 是否符合~
(1)
For i As Integer = 1 To 10
     If i = 3 Then
          If CDate(arr(i + 1)).ToShortDateString = "1900/1/1" Then
               C.Text = "尚無資料"
          End If
     End If
Next

或者
當更改判斷式 If AndAlso 判i不符合~ 就不會再判斷 arr(i + 1) 是否符合~
(2)

For i As Integer = 1 To 10

     If i = 3 And CDate(arr(i + 1)).ToShortDateString = "1900/1/1" Then
          C.Text = "尚無資料"
     End If

Next


或者
在判斷式之前 必須判斷 arr(i+1) 是否為日期型態
(3)
For i As Integer = 1 To 10

If IsDate(arr(i + 1)) = True Then
     '是日期型態
     If i = 3 And CDate(arr(i + 1)).ToShortDateString = "1900/1/1" Then
          C.Text = "尚無資料"
     End If
Else
     '不是日期型態
End If
Next


參考:

運算子 AndAlso 和 OrElse
VB.NET's Logical Operators AndAlso and OrElse









2012年11月8日 星期四

[除錯] DataGridView1.CurrentRow with EVENT DataGridView1_SelectionChanged

問題(problem):
點選 DataGridView 的表頭(Header)會錯誤 

錯誤訊息(Error Msg):
並未將物件參考設定為物件的執行個體

Private Sub DataGridView1_SelectionChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles DataGridView1.SelectionChanged
   
     '出錯的Code
     If DataGridView1.CurrentRow.Index <> -1 Then
           'do something
     End If
     
     '改成物件是否 Nothing
      If DataGridView1.CurrentRow IsNot Nothing Then
           'do something
      End If
End Sub

或改成


'確定是否點選到DataGridView的某行資料列 [C#]
if (this.DataGridView.SelectedRows.Count != 0) {}

DataGridView - EditOnEnter
DataGridView 控制項 (Windows Form)