将所有可见单元格定义在一个范围的行中

时间:2017-07-22 17:15:51

标签: vba excel-vba excel

我需要定义每个Cells在序列范围内的行如果面对一个隐藏列。 在下面的代码的尖锐区域中,当到达特定行中的隐藏列时,跳转到下一行,最后引用此行的继续并分配给RngCell变量。

我希望当For Each循环到达隐藏列时,继续将单元格分配给适当行的下一个可见单元格。

Sub CsvExportRange(rngRange As Range, strFileName As Variant, strCharset As String)

    Dim rngRow As Range
    Dim objStream As Object

    Set objStream = CreateObject("ADODB.Stream")
    objStream.Type = 2
    objStream.Charset = strCharset
    objStream.Open

    OffColumns (True)
    Call Tax_WP

    For Each rngRow In rngRange.Rows 'The problem becuase Here
        objStream.WriteText CsvFormatRow(rngRow) 
    Next rngRow

    objStream.SaveToFile strFileName, 2
    objStream.Close
End Sub
Function CsvFormatRow(rngRow As Range) As String

    Dim arrCsvRow() As String
    Dim strRowEnd As String

    strRowEnd = vbCrLf

    ReDim arrCsvRow(rngRow.Cells.Count - 1)
    Dim rngCell As Range
    Dim lngIndex As Long

    lngIndex = 0

    For Each rngCell In rngRow.Cells '***Problem is Here***
        arrCsvRow(lngIndex) = CsvFormatString(rngCell.Value)
        lngIndex = lngIndex + 1
    Next rngCell


    CsvFormatRow = Join(arrCsvRow, ",") & vbCrLf

End Function
Function CsvFormatString(strRaw As String) As String

    Dim boolNeedsDelimiting As Boolean

    Dim strDelimiter, strSeparator, strDelimiterEscaped As String

    strDelimiter = """"
    strSeparator = strSeparator = ","
    strDelimiterEscaped = strDelimiter & strDelimiter

    boolNeedsDelimiting = InStr(1, strRaw, strDelimiter) > 0 _
        Or InStr(1, strRaw, chr(10)) > 0 _
        Or InStr(1, strRaw, strSeparator) > 0

    CsvFormatString = strRaw

    If boolNeedsDelimiting Then
        CsvFormatString = strDelimiter & _
            Replace(strRaw, strDelimiter, strDelimiterEscaped) & _
            strDelimiter
    End If

End Function

2 个答案:

答案 0 :(得分:1)

当你遇到一个隐藏的专栏时,我很难理解你想要发生什么。在你的帖子中你说“跳到下一行”,但是然后用粗体表示,“继续将单元格分配给适当行的下一个可见单元格”,这一点不清楚,但可能意味着你希望继续行,但跳过隐藏的栏目?

你还使用一个与rngRow.Cells.Count - 1结合的数组,它总是可以让你获得16,383来定义你的数组。如果在循环遍历行时动态更新数组,或者只是将文本串在一起变为单个变量,可能会更容易?

你最终是想避免一堆“,,”吗?如果是这样,这种方法可能会更好。

总之,以下代码将:

  • rngCell位于隐藏列中时,结束您的CSVFormatRow功能。
  • rngCell位于CSV文件的任何行的使用范围之外的列中时(不仅仅是它循环的行),结束CSVFormatRow函数。
  • 代码不是使用数组,而是将成员串联到变量StrinCVSRow
  • 排除,
  • 中的最终StrinCVSRow

如果这不能解决您的问题,请澄清要求。希望这会有所帮助。

Function CsvFormatRow(rngRow As Range) As String

    'Dim arrCsvRow() As String

    Dim StrinCVSRow As String 'new variable to string row text together.

    Dim strRowEnd As String 'these two lines aren't doing anything
    strRowEnd = vbCrLf      'these two lines aren't doing anything

    'ReDim arrCsvRow(rngRow.Cells.Count - 1) ' always equals 16383
    Dim rngCell As Range

    'Dim lngIndex As Long ' (not needed if Array omitted)

    'lngIndex = 0

    For Each rngCell In rngRow.Cells '***Problem is Here***
        If rngCell.EntireColumn.Hidden = True Then
            'The "Exit For" will end the code here and jump to next row.
            'If you wanted to continue through the row you can leave
            'this condition in, but delete the "Exit For"
            'and this will simply "skip" this particular column.
            Exit For
        ElseIf Intersect(rngCell, Sheets(rngCell.Sheet.Name).UsedRange) Is Nothing Then
            'ends loop if last column with any data in entire CSV file is reached.
            Exit For

        Else
            StrinCVSRow = CsvFormatString(rngCell.Value) & ","
     '       lngIndex = lngIndex + 1
        End If

    Next rngCell

    'CsvFormatRow = Join(arrCsvRow, ",") & vbCrLf

    'left function trims off final ",".
    CsvFormatRow = Left(StrinCVSRow, Len(StrinCVSRow) - 1) & vbCrLf

End Function

答案 1 :(得分:0)

在下面的代码中,我找到了一种方法,真正捕获所有可见单元格在表格行中,并集成SpecialCells(12)Fore eachFor i

(在上述位置写入插入评论)

Sub CsvExportRange(rngRange As Object, strFileName As String, strCharset As String)

    Dim rngRow As Range
    Dim objStream As Object
    Dim i, lngFR As Long 'First Row

    lngFR = rngRange.SpecialCells(xlCellTypeVisible).Rows(1).Row - rngRange.Rows(1).Row + 1 'giving absolute Row number of first Table's row.

    Set objStream = CreateObject("ADODB.Stream")
    objStream.Type = 2
    objStream.Charset = strCharset
    objStream.Open
    For i = lngFR To lngFR + rngRange.SpecialCells(xlCellTypeVisible).Rows.Count - 1
        objStream.WriteText CsvFormatRow(rngRange.Rows(i)) 'Gives all visible lines are in table entirely of sheet. (Here using Fore i... is suitable)
    Next i

    objStream.SaveToFile strFileName, 2
    objStream.Close
End Sub
Function CsvFormatRow(rngRow As Variant) As String

    Dim arrCsvRow() As String
    Dim strRowEnd As String

    strRowEnd = vbCrLf

    ReDim arrCsvRow(rngRow.SpecialCells(xlCellTypeVisible).Cells.Count - 1) 'Defining array dimension for saving each cell in a array room and at last using Join() command
    Dim rngCell As Range
    Dim lngIndex As Long

    lngIndex = 0

    For Each rngCell In rngRow.SpecialCells(xlCellTypeVisible).Cells 'Here we used For Each to give only visible cells of above entire line so thats line is there in Table range.
        arrCsvRow(lngIndex) = CsvFormatString(rngCell.Value)
        lngIndex = lngIndex + 1
    Next rngCell

    CsvFormatRow = Join(arrCsvRow, ",") & vbCrLf 'At last, here generating destination CSV file data file.

End Function
Function CsvFormatString(strRaw As String) As String

    Dim boolNeedsDelimiting As Boolean

    Dim strDelimiter, strSeparator, strDelimiterEscaped As String

    strDelimiter = """"
    strSeparator = strSeparator = ","
    strDelimiterEscaped = strDelimiter & strDelimiter

    boolNeedsDelimiting = InStr(1, strRaw, strDelimiter) > 0 _
        Or InStr(1, strRaw, chr(10)) > 0 _
        Or InStr(1, strRaw, strSeparator) > 0

    CsvFormatString = strRaw

    If boolNeedsDelimiting Then
        CsvFormatString = strDelimiter & _
            Replace(strRaw, strDelimiter, strDelimiterEscaped) & _
            strDelimiter
    End If

End Function