【问题标题】:Formatting text output from DataGridView in vb.net在 vb.net 中格式化从 DataGridView 输出的文本
【发布时间】:2014-10-21 19:20:19
【问题描述】:

我正在将两个(1 列)DGV 和一个文本框的值写入文本文件。文本框值是标题,DGV1 是一列字符串(例如 SI CA S C...等),DGV2 是一列格式为 11.23 或 0.01 的数字。这些格式正是我希望它们在 DGV 中显示的方式,但是这种格式不会延续到这些值输出到的文本文件中。这是我希望文本文件的样子:

A012345 101 1.03
SI 32.13
C   1.45
CA  0.03

这就是我得到的:

A012345 101 1.03
SI32.13015
C1.452359
CA0.032568

代码如下:

 Try
        Dim da, da2 As OleDbDataAdapter
        Dim ds, ds2 As DataSet

        'open connection to nit2.xlsm'
        Dim cn As New OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=""" & TextBox2.Text & """;Extended Properties=""Excel 12.0;HDR=YES;""")

        'Fill dataviewgrid1 with element symbols, string, once'
        da = New OleDbDataAdapter("select * from [Sheet1$A:A" & lastrow & "]", cn)
        ds = New System.Data.DataSet
        da.Fill(ds)
        DataGridView1.DataSource = ds.Tables(0)


        '''''''''''''loop through each sample and write to text file'''''''''''''''''''''''
        da2 = New OleDbDataAdapter("select * from [Sheet1$B:B" & lastrow & "]", cn)
        ds2 = New System.Data.DataSet
        da2.Fill(ds2)
        DataGridView2.DataSource = ds2.Tables(0)

        'write sample heading to textbox1, looped'
        TextBox1.Text = "Q0" & xlWsheet1.Cells(1, 2).Value & " " & xlWsheet2.Cells(1, 2).Value


        'write to text file each data analysis point with formatted heading, looped'
        Dim title As String = TextBox1.Text
        Dim sub_title As String = title.Substring(0, 16)

        Using writer As New System.IO.StreamWriter(fName, True)
            writer.WriteLine(sub_title) 'heading'

            Dim symbol, SymbolT As String
            Dim compo As String
            For cell1 As Integer = 0 To (DataGridView1.Rows.Count - 2)
                symbol = Me.DataGridView1(0, cell1).Value 'element symbol'
                symbolT = symbol.Trim
                compo = Me.DataGridView2(0, cell1).Value 'composition'
                writer.WriteLine(symbolT & compo)
            Next

            writer.Close()
        End Using

        cn.Close()

如何格式化 DGV2 中的数字,使其仅显示为 2 位小数?

我还需要设置 SI 和 32.13 之间的间距(例如),以便每行中的小数点对齐。

正在格式化...有人吗?

【问题讨论】:

  • 顺便说一句,不要错过For cell1 As Integer = 0 To (DataGridView1.Rows.Count - 2) 的一行 - 似乎最后一行有点左(除非该行是空的,这是有道理的)
  • 是的,感谢 fsintegral。我想这是早期版本遗留下来的。好眼力!

标签: vb.net file text datagridview


【解决方案1】:

这样的?

Dim symbol As String
Dim compo As String
Dim symbolSpan As Integer = 0 ' stores the MaxLength of symbol
Dim compoSpan As Integer = 0 ' stores the Max Integer Part Length of compo
Dim symbolList As New List(Of String) ' all trimmed symbol
Dim compoList As New List(Of String) ' all trimmed compo
Dim compoIntLengthList As New List(Of Integer)
Dim doubleValue As Double
Dim i As Integer
Dim j As Integer

For i = 0 To (DataGridView1.Rows.Count - 2)
    ' element symbol...
    symbol = Me.DataGridView1(0, i).Value.ToString().Trim()
    symbolList.Add(symbol)
    If symbol.Length > symbolSpan Then
        symbolSpan = symbol.Length
    End If

    ' composition...
    If Double.TryParse(Me.DataGridView2(0, i).Value.ToString().Trim(), doubleValue) Then
        compoList.Add(doubleValue.ToString("R"))
        ' well, the ToString("R") is not really the displayed value.
        ' if your DGV allows scientific display for Double then 
        ' you'll have to handle that here with another code...
        compo = doubleValue.ToString("F0") ' gets the Integer part length...
        compoIntLengthList.add(compo.Length)
        If compo.Length > compoSpan Then
            compoSpan = compo.Length
        End If
    Else
        ' ohhhh ! the Cell doesn't contain a valid number... :/ 
        compo = Me.DataGridView2(0, i).Value.ToString().Trim()
        compoList.Add(compo)
        If compo.Contains(".") Then ' Watch out culture about dots and commas...
            If compoSpan < compo.IndexOf("."c) Then
                compoSpan = compo.IndexOf("."c)
            End If
            compoIntLengthList.add(compo.IndexOf("."c))
        Else
            If compoSpan < compo.Length Then
                compoSpan = compo.Length
            End If
            compoIntLengthList.add(compo.Length)
        End If
    End If
Next

symbolSpan = symbolSpan + 1 ' space between symbol and compo.

Using writer As New System.IO.StreamWriter(fName, True)
    writer.WriteLine(sub_title) 'heading'

    For i = 0 To symbolList.Count - 1
        symbol = symbolList.Item(i)
        While symbol.Length < symbolSpan
            symbol = symbol + " "
        End While

        compo = compoList.Item(i)
        j = compoIntLengthList.Item(i)
        While j < compoSpan
            compo = " " + compo
            j = j + 1 ' this is what was causing the endless loop.
        End While

        writer.WriteLine(symbol & compo)
    Next
    symbolList.Clear()
    symbolList= Nothing
    compoList.Clear()
    compoList = Nothing
    compoIntLengthList.Clear()
    compoIntLengthList = Nothing

    writer.Close()
End Using

我还没有测试过代码。 只是临时写的.. 这种方法看起来很难看(我同意),但这是我迄今为止记得的一种方法。 String.FormatStringBuilder 可能会更好,但我不记得它们是如何工作的,抱歉。


编辑:错过了两位小数部分...

哦,对不起!你只需要两位小数。替换这个:

        compoList.Add(doubleValue.ToString("R"))

通过这个:

        compoList.Add(doubleValue.ToString("F2"))
        ' or this :
        compoList.Add(doubleValue.ToString("#.##")) ' to allow 0 or 1 decimal aswell

并替换这部分:

        ' ohhhh ! the Cell doesn't contain a valid number... :/ 
        compo = Me.DataGridView2(0, i).Value.ToString().Trim()
        compoList.Add(compo)
        If compo.Contains(".") Then ' Watch out culture about dots and commas...
            If compoSpan < compo.IndexOf("."c) Then
                compoSpan = compo.IndexOf("."c)
            End If
            compoIntLengthList.add(compo.IndexOf("."c))
        Else
            If compoSpan < compo.Length Then
                compoSpan = compo.Length
            End If
            compoIntLengthList.add(compo.Length)
        End If

通过这个:

        ' ohhhh ! the Cell doesn't contain a valid number... :/ 
        compo = Me.DataGridView2(0, i).Value.ToString().Trim()
        If compo.Contains(".") Then ' Watch out culture about dots and commas...
            If compoSpan < compo.IndexOf("."c) Then
                compoSpan = compo.IndexOf("."c)
            End If
            If compo.Length > (compo.IndexOf("."c) + 3) Then
                compo = compo.SubString(0, compo.IndexOf("."c) + 3)
            End If
            compoIntLengthList.add(compo.IndexOf("."c))
        Else
            If compoSpan < compo.Length Then
                compoSpan = compo.Length
            End If
            compoIntLengthList.add(compo.Length)
        End If
        compoList.Add(compo)

【讨论】:

  • 我添加了一些关于两位小数的东西(错过了)
  • 我在运行时遇到空引用异常错误:对象引用未设置为对象的实例。它会在行开头弹出 - symbol = Me.DataGridView1(0, i).Value.ToString().Trim
  • 嗯,DGV 引用已设置好...我在想 ToString 方法试图将空值转换为字符串? DGV1 的标题是“SAMPLE”,但它不应该是这样读的。第一行是“SI”,这应该不是问题。当然,我没有任何空单元格...
  • 异常发生时调试器中“i”的值是多少?它应该突出显示有问题的行..
  • @BG- :DataGridView 行为:如果您允许用户添加一行(属性AllowUserToAddRows)并且DGV 将RowHeadersVisible 属性设置为True,那么它会自动添加表格末尾的空行。这就是为什么我在另一条评论中说 "... (除非该行是空的,这是有道理的)" 。对于那个空行,For cell1 As Integer = 0 To (DataGridView1.Rows.Count - 2) 是正确的:丢弃最后一个(空)行(这取决于 DGV 属性和/或是否可以在运行时更改)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多