Excel 是否有一种正确的方法来执行此任务,而不必求助于定制的子例程? 问题摘要

Excel 是否有一种正确的方法来执行此任务,而不必求助于定制的子例程? 问题摘要,excel,ms-access,vba,Excel,Ms Access,Vba,我在VBA中编写了一个excel宏,它导入一个大文本文件,读取每一行以确定要存储的数据数量,为保存数据的数组分配正确的大小,然后再次打开该文件以将数据写入数组 我在这个程序中遇到的问题是,大文本文件的每行选项卡大小不一致。我必须编写一个特殊的定界过滤器函数来选择要存储到数组中的正确数据 是否有一种正确的方法来执行此任务,而不必求助于定制的子例程 程序规格 程序必须执行数据分析,以便与以下模型进行最佳拟合,$y_k=c_1 x_k+c_0+c_{-1}(x_{k})^{-1}$,其中包括负指数。程

我在VBA中编写了一个excel宏,它导入一个大文本文件,读取每一行以确定要存储的数据数量,为保存数据的数组分配正确的大小,然后再次打开该文件以将数据写入数组

我在这个程序中遇到的问题是,大文本文件的每行选项卡大小不一致。我必须编写一个特殊的定界过滤器函数来选择要存储到数组中的正确数据

是否有一种正确的方法来执行此任务,而不必求助于定制的子例程

程序规格 程序必须执行数据分析,以便与以下模型进行最佳拟合,
$y_k=c_1 x_k+c_0+c_{-1}(x_{k})^{-1}$
,其中包括负指数。程序不能允许数据在退出后保留在Excel电子表格中,但这并不意味着不能临时放置数据。对于不耐烦的用户来说,性能和速度非常重要。导入的数据可以具有未指定数量的重复列类型和未定义的制表符长度定界

接受建议 我愿意利用预定义的excel函数,并将数据暂时存储在excel变量中

确定文本文件中数据的大小 重新打开文本文件并将所有数据存储到数组中 定界提取函数 也许这会有帮助:

Function extractNumbers(line As String) As Variant
    Dim v As Variant
    Dim n As Long, i As Long
    Dim c As New Collection
    v = Split(line)
    For i = LBound(v) To UBound(v)
        If Len(v(i)) > 0 And IsNumeric(v(i)) Then c.Add v(i)
    Next i
    n = c.Count
    If n = 0 Then Exit Function
    v = Empty
    ReDim v(0 To n - 1)
    For i = 0 To n - 1
        v(i) = CDbl(c.Item(i + 1))
    Next i
    extractNumbers = v
End Function

Sub test(line As String)
    Dim i As Long
    Dim s As String
    Dim v As Variant
    v = extractNumbers(line)
    If Not IsEmpty(v) Then
        For i = 0 To UBound(v)
            s = s & " " & v(i)
        Next i
        Debug.Print Trim(s)
    Else
        Debug.Print "No numbers found"
    End If
End Sub
典型输出:

test "Run #1  Run #1  Run #1  Run #1  Run #1  Run #2  Run #2  Run #2  Run #2  Run #2"
No numbers found
test "5.000E-5    -0.024      1.26E-6 0.05    5.000E-5    0.078       1.26E-6 0.05"
0.00005 -0.024 0.00000126 0.05 0.00005 0.078 0.00000126 0.05
test "5.000E-5    -0.024   bob   1.26E-6 0.05    5.000E-5    0.078       1.26E-6 0.05"
0.00005 -0.024 0.00000126 0.05 0.00005 0.078 0.00000126 0.05
你能用这个吗



这就是以制表符分隔的文件的结构:

您可以使用Split访问(和处理)每个数据元素

dat = Split(dat, vbCrLf)    'generates an array of lines

dat = Split(dat, vbTab)     'generates an array of data items for each line

你能举个例子说明你要替换的内容(以及替换文本)和你当前的代码吗?如果你能提供一个导入数据的小样本,显示不一致的制表符大小,如@Jane所述,以及你的分隔符函数,该函数可以根据需要解析行。这将允许我们确定一些模式,以及我们是否可以以其他方式(不使用自定义子例程)在函数中应用逻辑@Jane代码是available@paulbica代码是可用的为什么不使用Get External Data将txt文件读入Excel?您可以将定界符指定为tab和space:works OK,用于示例数据。然后将Excel中的数据直接读取到一个数组中。您的代码如何识别数字而不是数字?@linuxfreebird我的代码假设所讨论的行由数字和空格组成,因为您发布的示例就是这样的。我修改了代码并添加了一个IsNumeric()检查。
Run #1  Run #1  Run #1  Run #1  Run #1  Run #2  Run #2  Run #2  Run #2  Run #2
Time (s)    Voltage (V) Output Frequency (Hz)   Calc3 (units)   w   Time (s)    Voltage (V) Output Frequency (Hz)   Calc3 (units)   w
0.000   -0.060  69.940  0.00    0.00    0.000   0.034   29.980  0.00    0.00
5.000E-5    -0.024      1.26E-6 0.05    5.000E-5    0.078       1.26E-6 0.05
1.000E-4    0.059       2.51E-6 0.10    1.000E-4    -0.045      2.51E-6 0.10
1.500E-4    0.008       3.77E-6 0.15    1.500E-4    -0.056      3.77E-6 0.15
2.000E-4    -0.051      5.03E-6 0.20    2.000E-4    0.055       5.03E-6 0.20
2.500E-4    0.008       6.28E-6 0.25    2.500E-4    0.039       6.28E-6 0.25
3.000E-4    0.047       7.54E-6 0.30    3.000E-4    -0.056      7.54E-6 0.30
3.500E-4    -0.013      8.80E-6 0.35    3.500E-4    -0.021      8.80E-6 0.35
4.000E-4    -0.035      1.01E-5 0.40    4.000E-4    0.055       1.01E-5 0.40
4.500E-4    0.023       1.13E-5 0.45    4.500E-4    0.007       1.13E-5 0.45
5.000E-4    0.028       1.26E-5 0.50    5.000E-4    -0.049      1.26E-5 0.50
5.500E-4    -0.024      1.38E-5 0.55    5.500E-4    0.007       1.38E-5 0.55
6.000E-4    -0.017      1.51E-5 0.60    6.000E-4    0.043       1.51E-5 0.60
6.500E-4    0.027       1.63E-5 0.65    6.500E-4    -0.013      1.63E-5 0.65
7.000E-4    0.011       1.76E-5 0.70    7.000E-4    -0.033      1.76E-5 0.70
7.500E-4    -0.026      1.88E-5 0.75    7.500E-4    0.022       1.88E-5 0.75
8.000E-4    -4.272E-4       2.01E-5 0.80    8.000E-4    0.027       2.01E-5 0.80
8.500E-4    0.026       2.14E-5 0.85    8.500E-4    -0.022      2.14E-5 0.85
9.000E-4    -0.001      2.26E-5 0.90    9.000E-4    -0.016      2.26E-5 0.90
9.500E-4    -0.019      2.39E-5 0.95    9.500E-4    0.026       2.39E-5 0.95
0.001   0.009       2.51E-5 1.00    0.001   0.009       2.51E-5 1.00
0.001   0.017       2.64E-5 1.05    0.001   -0.022      2.64E-5 1.05
0.001   -0.010      2.76E-5 1.10    0.001   -0.002      2.76E-5 1.10
0.001   -0.011      2.89E-5 1.15    0.001   0.023       2.89E-5 1.15
0.001   0.013       3.02E-5 1.20    0.001   -0.002      3.02E-5 1.20
0.001   0.010       3.14E-5 1.25    0.001   -0.017      3.14E-5 1.25
0.001   -0.011      3.27E-5 1.30    0.001   0.007       3.27E-5 1.30
0.001   -0.002      3.39E-5 1.35    0.001   0.017       3.39E-5 1.35
0.001   0.013       3.52E-5 1.40    0.001   -0.008      3.52E-5 1.40
0.001   0.003       3.64E-5 1.45    0.001   -0.010      3.64E-5 1.45
0.002   -0.009      3.77E-5 1.50    0.002   0.012       3.77E-5 1.50
0.002   0.004       3.90E-5 1.55    0.002   0.010       3.90E-5 1.55
0.002   0.012       4.02E-5 1.60    0.002   -0.010      4.02E-5 1.60
0.002   -0.001      4.15E-5 1.65    0.002   -0.004      4.15E-5 1.65
0.002   -0.008      4.27E-5 1.70    0.002   0.012       4.27E-5 1.70
0.002   0.005       4.40E-5 1.75    0.002   0.004       4.40E-5 1.75
0.002   0.007       4.52E-5 1.80    0.002   -0.010      4.52E-5 1.80
0.002   -0.004      4.65E-5 1.85    0.002   0.003       4.65E-5 1.85
0.002   -0.001      4.78E-5 1.90    0.002   0.010       4.78E-5 1.90
0.002   0.005       4.90E-5 1.95    0.002   -0.002      4.90E-5 1.95
0.002   0.004       5.03E-5 2.00    0.002   -0.005      5.03E-5 2.00
0.002   -0.005      5.15E-5 2.05    0.002   0.006       5.15E-5 2.05
0.002   -9.155E-4       5.28E-5 2.10    0.002   0.006       5.28E-5 2.10
0.002   0.005       5.40E-5 2.15    0.002   -0.003      5.40E-5 2.15
Function extractNumbers(line As String) As Variant
    Dim v As Variant
    Dim n As Long, i As Long
    Dim c As New Collection
    v = Split(line)
    For i = LBound(v) To UBound(v)
        If Len(v(i)) > 0 And IsNumeric(v(i)) Then c.Add v(i)
    Next i
    n = c.Count
    If n = 0 Then Exit Function
    v = Empty
    ReDim v(0 To n - 1)
    For i = 0 To n - 1
        v(i) = CDbl(c.Item(i + 1))
    Next i
    extractNumbers = v
End Function

Sub test(line As String)
    Dim i As Long
    Dim s As String
    Dim v As Variant
    v = extractNumbers(line)
    If Not IsEmpty(v) Then
        For i = 0 To UBound(v)
            s = s & " " & v(i)
        Next i
        Debug.Print Trim(s)
    Else
        Debug.Print "No numbers found"
    End If
End Sub
test "Run #1  Run #1  Run #1  Run #1  Run #1  Run #2  Run #2  Run #2  Run #2  Run #2"
No numbers found
test "5.000E-5    -0.024      1.26E-6 0.05    5.000E-5    0.078       1.26E-6 0.05"
0.00005 -0.024 0.00000126 0.05 0.00005 0.078 0.00000126 0.05
test "5.000E-5    -0.024   bob   1.26E-6 0.05    5.000E-5    0.078       1.26E-6 0.05"
0.00005 -0.024 0.00000126 0.05 0.00005 0.078 0.00000126 0.05
Option Explicit

Public Sub SpecesToTabs()

    Const MAX_SPACES    As Long = 10
    Const FILE_NAME     As String = "C:\test.txt"

    Dim fso As Object, txt As Object, dat As String, i As Long

    Set fso = CreateObject("Scripting.FileSystemObject")

    Set txt = fso.OpenTextFile(FILE_NAME)           'open file for reading

    dat = txt.ReadAll                               'read entire file

    If Len(dat) > 0 Then
        For i = MAX_SPACES To 2 Step -1
            dat = Replace(dat, Space(i), vbTab)     'replace space sets with tabs
        Next

        Set txt = fso.OpenTextFile(FILE_NAME, 2)    'open file for writing
        txt.Write dat                               'write back to text file"
    End If
End Sub
dat = Split(dat, vbCrLf)    'generates an array of lines

dat = Split(dat, vbTab)     'generates an array of data items for each line