Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel和VBA在宏中中途崩溃_Vba_Excel_Text - Fatal编程技术网

Excel和VBA在宏中中途崩溃

Excel和VBA在宏中中途崩溃,vba,excel,text,Vba,Excel,Text,我是VBA新手,希望能对实现用户定义函数有所帮助。我真的很感激任何帮助 上下文:我正在尝试将一批固定宽度的文本文件导入单独的Excel工作簿。文本文件都具有相同的字段和格式。我知道每个字段的长度。目前,我正试图让我的VBA代码为单个文本文件工作 问题:由于我是VBA新手,我查找了现有代码。我发现,并一直试图实现我的TestImport函数(见下文)。(*请注意,…只是为了简洁起见-实际上没有包含在代码中。) 请参阅本文末尾的ImportFixedWidth函数 然后我尝试在工作簿中运行宏,但每次

我是VBA新手,希望能对实现用户定义函数有所帮助。我真的很感激任何帮助

上下文:我正在尝试将一批固定宽度的文本文件导入单独的Excel工作簿。文本文件都具有相同的字段和格式。我知道每个字段的长度。目前,我正试图让我的VBA代码为单个文本文件工作

问题:由于我是VBA新手,我查找了现有代码。我发现,并一直试图实现我的TestImport函数(见下文)。(*请注意,…只是为了简洁起见-实际上没有包含在代码中。)

请参阅本文末尾的ImportFixedWidth函数

然后我尝试在工作簿中运行宏,但每次都会导致VBA和Excel崩溃。第一个字段(不是其他字段)导入到打开的工作簿中,但程序停止响应,必须退出

调试:代码编译。在单步执行TestImport或ImportFixedWidth代码时,我没有收到任何错误。我试过在Mac和Windows PC上运行宏(它在两台电脑上都崩溃)。第一个字段在程序崩溃之前被正确导入,所以我不确定问题出在哪里

问题:就调试而言,我不知道接下来的步骤。我的实现中有没有明显的错误?我的下一个逻辑调试步骤是什么

Function ImportFixedWidth(FileName As String, _
    StartCell As Range, _
    IgnoreBlankLines As Boolean, _
    SkipLinesBeginningWith As String, _
    ByVal FieldSpecs As String) As Long
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' ImportFixedWidth
' By Chip Pearson, chip@cpearson.com www.cpearson.com
' Date: 27-August-2011
' Compatible with 64-bit platforms.
'
' This function imports text from a fixed field width file.
' FileName is the name of the file to import. StartCell is
' the cell in which the import is to begin. IgnoreBlankLines
' indicates what to do with empty lines in the text file. If
' IgnoreBlankLines is False, an empty row will appear in the
' worksheet. If IgnoreBlankLines is True, no empty row will
' appear in the worksheet. SkipLinesBeginingWith indicates
' what character, if any, at the begining of the line indicates
' that the line should not be imported, such as fpr providing for
' comments within the text file. FieldSpecs indicates how to
' map the data into cells. It is a string of the format:
'           start,length|start,length|start,length...
' where each 'start' is the character position of the field
' in the text line and each 'length' is the length of the field.
' For example, if FieldSpecs is
'           1,8|9,3|12,5
' indicates the first field starting in position 1 for a
' length of 8, the second field starts in position 9 for a
' length of 3, and finally a field beginning in position 12
' for a length of 5. Fields can be in any order and may
' overlap.
' You can specify a number format for the field which will
' be applied to the worksheet cell. This format should not
' be in quotes and should follow the length element. For example,
'       2,8|9,3,@|12,8,dddd dd-mmm-yyyy
' This specifies that no formatting will be applied to column 2,
' the Text (literal) format will be applied to column 9, and
' the format 'dddd dd-mmm-yyyy' will be applied to column 12.
'
' The function calls ImportThisLine, which should return
' True to import the text from the file, or False to skip
' the current line.
' This function returns the number of records imported if
' successful or -1 if an error occurred.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Dim FINdx As Long
Dim C As Long
Dim R As Range
Dim FNum As Integer
Dim S As String
Dim RecCount As Long
Dim FieldInfos() As String
Dim FInfo() As String
Dim N As Long
Dim T As String
Dim B As Boolean

Application.EnableCancelKey = xlInterrupt
On Error GoTo EndOfFunction:

If Dir(FileName, vbNormal) = vbNullString Then
    ' file not found
    ImportFixedWidth = -1
    Exit Function
End If

If Len(FieldSpecs) < 3 Then
    ' invalid FieldSpecs
    ImportFixedWidth = -1
    Exit Function
End If

If StartCell Is Nothing Then
    ImportFixedWidth = -1
    Exit Function
End If

Set R = StartCell(1, 1)
C = R.Column
FNum = FreeFile

Open FileName For Input Access Read As #FNum
' get rid of any spaces
FieldSpecs = Replace(FieldSpecs, Space(1), vbNullString)
' omit double pipes ||
N = InStr(1, FieldSpecs, "||", vbBinaryCompare)
Do Until N = 0
    FieldSpecs = Replace(FieldSpecs, "||", "|")
    N = InStr(1, FieldSpecs, "||", vbBinaryCompare)
Loop
' omit double commas
N = InStr(1, FieldSpecs, ",,", vbBinaryCompare)
Do Until N = 0
    FieldSpecs = Replace(FieldSpecs, ",,", ",")
    N = InStr(1, FieldSpecs, ",,", vbBinaryCompare)
Loop

' get rid of leading and trailing | characters, if necessary
If StrComp(Left(FieldSpecs, 1), "|", vbBinaryCompare) = 0 Then
    FieldSpecs = Mid(FieldSpecs, 2)
End If
If StrComp(Right(FieldSpecs, 1), "|", vbBinaryCompare) = 0 Then
    FieldSpecs = Left(FieldSpecs, Len(FieldSpecs) - 1)
End If

Do
    ' read the file
    Line Input #FNum, S
    If SkipLinesBeginningWith <> vbNullString And _
            StrComp(Left(Trim(S), Len(SkipLinesBeginningWith)), _
            SkipLinesBeginningWith, vbTextCompare) Then
        If Len(S) = 0 Then
            If IgnoreBlankLines = False Then
                Set R = R(2, 1)
            Else
                ' do nothing
            End If
        Else
            ' allow code to change the FieldSpecs values

            If FieldSpecs = vbNullString Then
                ' FieldSpecs is empty. Do nothing, don't import.
            Else
                If ImportThisLine(S) = True Then
                    FieldInfos = Split(FieldSpecs, "|")
                    C = R.Column
                    For FINdx = LBound(FieldInfos) To UBound(FieldInfos)
                        FInfo = Split(FieldInfos(FINdx), ",")
                        R.EntireRow.Cells(1, C).Value = Mid(S, CLng(FInfo(0)), CLng(FInfo(1)))
                        C = C + 1
                    Next FINdx
                    RecCount = RecCount + 1
                End If
                Set R = R(2, 1)
            End If
        End If
    Else
        ' no skip first char
    End If

Loop Until EOF(FNum)

EndOfFunction:
If Err.Number = 0 Then
    ImportFixedWidth = RecCount
Else
    ImportFixedWidth = -1
End If
Close #FNum
End Function

Private Function ImportThisLine(S As String) As Boolean

Dim N As Long
Dim NoImportWords As Variant
Dim T As String
Dim L As Long

NoImportWords = Array("page", "product", "xyz")
For N = LBound(NoImportWords) To UBound(NoImportWords)
    T = NoImportWords(N)
    L = Len(T)
    If StrComp(Left(S, L), T, vbTextCompare) = 0 Then
        ImportThisLine = False
        Exit Function
    End If
Next N
ImportThisLine = True
End Function
函数ImportFixedWidth(文件名为字符串_
StartCell作为靶场_
将空白行忽略为布尔值_
从弦开始的技巧_
ByVal字段规格为字符串)长度相同
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'导入固定宽度
由奇普·皮尔森所作,chip@cpearson.comwww.cpearson.com
日期:2011年8月27日
'与64位平台兼容。
'
'此函数用于从固定字段宽度的文件导入文本。
'文件名是要导入的文件的名称。StartCell是
'要开始导入的单元格。忽略空白线
'指示如何处理文本文件中的空行。如果
'IgnoreBlankLines为False,将在
“工作表。如果IgnoreBlankLines为True,则不会显示空行
'显示在工作表中。以指示开头的Skiplines
'行开头的字符(如果有)表示什么
“该行不应导入,如fpr提供
'文本文件中的注释。FieldSpecs指明了如何
'将数据映射到单元格中。它是以下格式的字符串:
'开始,长度|开始,长度|开始,长度。。。
'其中每个'start'是字段的字符位置
,每个“长度”都是字段的长度。
'例如,如果FieldSpecs是
'           1,8|9,3|12,5
'表示从位置1开始的第一个字段
'长度为8,第二个字段从位置9开始
'长度为3,最后是从位置12开始的字段
“五分钟。字段可以是任何顺序,也可以是
“重叠。
'您可以指定字段的数字格式,该字段将
'将应用于工作表单元格。此格式不应
'在引号中,并应在长度元素后面。例如
'2,8 | 9,3,@| 12,8,dddd-dd-mmm-yyyy
'这指定不会对第2列应用任何格式,
'文本(文字)格式将应用于第9列,并且
'格式'dddd mmm yyyy'将应用于第12列。
'
'函数调用ImportThisLine,它应该返回
'如果为True,则从文件导入文本;如果为False,则跳过
'当前行。
'此函数返回在以下情况下导入的记录数:
'成功,如果发生错误,则为-1。
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Dim FINdx尽可能长
尺寸C与长度相同
调光范围
作为整数的Dim FNum
像线一样变暗
我认为时间很长
Dim FieldInfos()作为字符串
Dim FInfo()作为字符串
长
调暗T作为字符串
作为布尔值的dimb
Application.EnableCancelKey=xlInterrupt
错误转到EndOffFunction时:
如果Dir(FileName,vbNormal)=vbNullString,则
'找不到文件
ImportFixedWidth=-1
退出功能
如果结束
如果Len(现场规范)<3,则
'无效的字段规范
ImportFixedWidth=-1
退出功能
如果结束
如果StartCell什么都不是
ImportFixedWidth=-1
退出功能
如果结束
设置R=StartCell(1,1)
C=R.柱
FNum=FreeFile
打开输入访问的文件名,读取为#FNum
“去掉任何空格
FieldSpecs=替换(FieldSpecs,空格(1),vbNullString)
“省略双管||
N=InStr(1,字段规格,“| |”,vbBinaryCompare)
直到N=0为止
FieldSpecs=替换(FieldSpecs,“| |”、“|”)字段规格
N=InStr(1,字段规格,“| |”,vbBinaryCompare)
环
'省略双逗号
N=InStr(1,字段规格,,,,vbBinaryCompare)
直到N=0为止
FieldSpecs=替换(FieldSpecs,“,”,“,”,”)
N=InStr(1,字段规格,,,,vbBinaryCompare)
环
'如有必要,去掉前导字符和尾随字符
如果StrComp(左(FieldSpecs,1),“|”,vbBinaryCompare)=0,则
FieldSpecs=Mid(FieldSpecs,2)
如果结束
如果StrComp(右(FieldSpecs,1),“|”,vbBinaryCompare)=0,则
FieldSpecs=左侧(FieldSpecs,Len(FieldSpecs)-1)
如果结束
做
'读取文件
行输入#FNum,S
如果Skiplines从vbNullString开始,则_
StrComp(左侧(修剪),Len(Skiplines Beging with))_
Skiplines开始于,vbTextCompare)然后
如果Len(S)=0,则
如果IgnoreBlankLines=False,则
设置R=R(2,1)
其他的
“什么也不做
如果结束
其他的
'允许代码更改FieldSpecs值
如果FieldSpecs=vbNullString,则
“FieldSpecs为空。什么都不做,不要导入。
其他的
如果ImportThisLine=True,则
FieldInfos=Split(FieldSpecs,“|”)
C=R.柱
对于FINdx=LBound(FieldInfos)到UBound(FieldInfos)
Function ImportFixedWidth(FileName As String, _
    StartCell As Range, _
    IgnoreBlankLines As Boolean, _
    SkipLinesBeginningWith As String, _
    ByVal FieldSpecs As String) As Long
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' ImportFixedWidth
' By Chip Pearson, chip@cpearson.com www.cpearson.com
' Date: 27-August-2011
' Compatible with 64-bit platforms.
'
' This function imports text from a fixed field width file.
' FileName is the name of the file to import. StartCell is
' the cell in which the import is to begin. IgnoreBlankLines
' indicates what to do with empty lines in the text file. If
' IgnoreBlankLines is False, an empty row will appear in the
' worksheet. If IgnoreBlankLines is True, no empty row will
' appear in the worksheet. SkipLinesBeginingWith indicates
' what character, if any, at the begining of the line indicates
' that the line should not be imported, such as fpr providing for
' comments within the text file. FieldSpecs indicates how to
' map the data into cells. It is a string of the format:
'           start,length|start,length|start,length...
' where each 'start' is the character position of the field
' in the text line and each 'length' is the length of the field.
' For example, if FieldSpecs is
'           1,8|9,3|12,5
' indicates the first field starting in position 1 for a
' length of 8, the second field starts in position 9 for a
' length of 3, and finally a field beginning in position 12
' for a length of 5. Fields can be in any order and may
' overlap.
' You can specify a number format for the field which will
' be applied to the worksheet cell. This format should not
' be in quotes and should follow the length element. For example,
'       2,8|9,3,@|12,8,dddd dd-mmm-yyyy
' This specifies that no formatting will be applied to column 2,
' the Text (literal) format will be applied to column 9, and
' the format 'dddd dd-mmm-yyyy' will be applied to column 12.
'
' The function calls ImportThisLine, which should return
' True to import the text from the file, or False to skip
' the current line.
' This function returns the number of records imported if
' successful or -1 if an error occurred.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Dim FINdx As Long
Dim C As Long
Dim R As Range
Dim FNum As Integer
Dim S As String
Dim RecCount As Long
Dim FieldInfos() As String
Dim FInfo() As String
Dim N As Long
Dim T As String
Dim B As Boolean

Application.EnableCancelKey = xlInterrupt
On Error GoTo EndOfFunction:

If Dir(FileName, vbNormal) = vbNullString Then
    ' file not found
    ImportFixedWidth = -1
    Exit Function
End If

If Len(FieldSpecs) < 3 Then
    ' invalid FieldSpecs
    ImportFixedWidth = -1
    Exit Function
End If

If StartCell Is Nothing Then
    ImportFixedWidth = -1
    Exit Function
End If

Set R = StartCell(1, 1)
C = R.Column
FNum = FreeFile

Open FileName For Input Access Read As #FNum
' get rid of any spaces
FieldSpecs = Replace(FieldSpecs, Space(1), vbNullString)
' omit double pipes ||
N = InStr(1, FieldSpecs, "||", vbBinaryCompare)
Do Until N = 0
    FieldSpecs = Replace(FieldSpecs, "||", "|")
    N = InStr(1, FieldSpecs, "||", vbBinaryCompare)
Loop
' omit double commas
N = InStr(1, FieldSpecs, ",,", vbBinaryCompare)
Do Until N = 0
    FieldSpecs = Replace(FieldSpecs, ",,", ",")
    N = InStr(1, FieldSpecs, ",,", vbBinaryCompare)
Loop

' get rid of leading and trailing | characters, if necessary
If StrComp(Left(FieldSpecs, 1), "|", vbBinaryCompare) = 0 Then
    FieldSpecs = Mid(FieldSpecs, 2)
End If
If StrComp(Right(FieldSpecs, 1), "|", vbBinaryCompare) = 0 Then
    FieldSpecs = Left(FieldSpecs, Len(FieldSpecs) - 1)
End If

Do
    ' read the file
    Line Input #FNum, S
    If SkipLinesBeginningWith <> vbNullString And _
            StrComp(Left(Trim(S), Len(SkipLinesBeginningWith)), _
            SkipLinesBeginningWith, vbTextCompare) Then
        If Len(S) = 0 Then
            If IgnoreBlankLines = False Then
                Set R = R(2, 1)
            Else
                ' do nothing
            End If
        Else
            ' allow code to change the FieldSpecs values

            If FieldSpecs = vbNullString Then
                ' FieldSpecs is empty. Do nothing, don't import.
            Else
                If ImportThisLine(S) = True Then
                    FieldInfos = Split(FieldSpecs, "|")
                    C = R.Column
                    For FINdx = LBound(FieldInfos) To UBound(FieldInfos)
                        FInfo = Split(FieldInfos(FINdx), ",")
                        R.EntireRow.Cells(1, C).Value = Mid(S, CLng(FInfo(0)), CLng(FInfo(1)))
                        C = C + 1
                    Next FINdx
                    RecCount = RecCount + 1
                End If
                Set R = R(2, 1)
            End If
        End If
    Else
        ' no skip first char
    End If

Loop Until EOF(FNum)

EndOfFunction:
If Err.Number = 0 Then
    ImportFixedWidth = RecCount
Else
    ImportFixedWidth = -1
End If
Close #FNum
End Function

Private Function ImportThisLine(S As String) As Boolean

Dim N As Long
Dim NoImportWords As Variant
Dim T As String
Dim L As Long

NoImportWords = Array("page", "product", "xyz")
For N = LBound(NoImportWords) To UBound(NoImportWords)
    T = NoImportWords(N)
    L = Len(T)
    If StrComp(Left(S, L), T, vbTextCompare) = 0 Then
        ImportThisLine = False
        Exit Function
    End If
Next N
ImportThisLine = True
End Function
 On Error GoTo EndOfFunction:
 If InDebugMode then On Error Goto EndOfFunction:
 Public Const InDebugMode = True