удалить синие и пустые ячейки из xlsx с помощью vbscript

У меня есть vbscript, который преобразует определенный диапазон строк в файл csv.
Моя проблема в том, что он также копирует пустые строки и ненужные синие строки. Как я могу удалить эти полные пустые строки перед копированием или исключить их из копирования?
Мой код:

Public Sub xlsToCsv()    
    Const WorkingDir = "C:\Test\"
    Const xlCSV = 24
    Const xlUp = -4162

    Dim fso, SaveName, myFile
    Dim objExcel, objWorkbook, wsSource, wsTarget

    myFile = "source_file.xlsx"
    SaveName = "test.csv"

    With CreateObject("Scripting.FilesystemObject")
        If Not .FileExists(WorkingDir & myFile) Then
            MsgBox "File not found:" & vbCrLf & WorkingDir & myFile, vbInformation, "Script Cancelled"
            WScript.Quit
        End If
    End With

    Set objExcel = CreateObject("Excel.Application")

    objExcel.Visible = False
    objExcel.DisplayAlerts = False

    Set objWorkbook = objExcel.Workbooks.Open(WorkingDir & myFile)
    Set wsSource = objWorkbook.Sheets(1)
    Set wsTarget = objWorkbook.Sheets.Add()

    With wsTarget
    .Cells(1,1).Value = "ID"
    .Cells(1,2).Value = "NAME"
    .Cells(1,3).Value = "DESC"
    End With

    With wsSource
    .Range("F7", .Range("F" & .Rows.Count).End(xlUp)).Copy wsTarget.Range("A2")
    .Range("A7", .Range("A" & .Rows.Count).End(xlUp)).Copy wsTarget.Range("B2")
    .Range("E7", .Range("E" & .Rows.Count).End(xlUp)).Copy wsTarget.Range("C2")
    End With

    objWorkbook.SaveAs WorkingDir & SaveName, xlCSV
    objWorkbook.Close True

    Set objWorkbook = Nothing
    Set objExcel = Nothing
    Set fso = Nothing
    Set myFolder = Nothing
End Sub

call xlsToCsv()

person nolags    schedule 16.10.2017    source источник
comment
Вы можете автоматически фильтровать пустые ИЛИ синие строки и удалять их. А затем сделайте свой CSV.   -  person danieltakeshi    schedule 16.10.2017
comment
Мне это нужно не только для клеток. Мне нужно удалить строку, если полная строка пуста. Могу ли я фильтровать для этого? Как я могу отфильтровать синие ячейки?   -  person nolags    schedule 16.10.2017
comment
попробовал эту команду wsSource.Range(A:F).Cells.SpecialCells(xlCellTypeBlanks).EntireRow.Delete завершился с кодом ошибки 800A03EC - свойство специальных ячеек объекта диапазона не может быть назначено.   -  person nolags    schedule 16.10.2017
comment
У меня работает без этой ошибки, см. это. И обратите внимание, что вы удаляете всю строку, поэтому, если у вас есть пустые значения в строке A и непустые в F, вы потеряете значения в F   -  person danieltakeshi    schedule 16.10.2017
comment
Я хочу проверить, пуста ли полная строка, а затем удалить всю строку.   -  person nolags    schedule 16.10.2017
comment
До сих пор нет рабочего решения!   -  person nolags    schedule 16.10.2017


Ответы (2)


Это альтернативный подход к моему оригиналу в попытке улучшить производительность. В этом случае вместо использования Excel для создания CSV-файла код VBScript записывает CSV-файл напрямую, используя текстовый файл, созданный FileSystemObject. Я протестировал это с большим набором исходных данных, и, похоже, это немного быстрее, чем оригинал — около 40 секунд для 1500 строк. Открытие приложения Excel по-прежнему связано с накладными расходами (около 5-10 секунд), но с этим мало что можно поделать. Если для вас важна производительность, вы можете внести и другие улучшения.

Если у вас есть числовые значения в электронной таблице, вам может потребоваться выполнить некоторое форматирование для преобразования в строковые значения, подходящие для вывода csv, поскольку Excel обычно использует экспоненциальное представление для чисел, преобразованных в текст, что не всегда вам нужно. Я также использовал кавычки и запятые-разделители, но вы можете использовать другие правила форматирования для вывода CSV. Вы можете захотеть изменить использование WriteLine, потому что это добавляет CrLf после последней строки, которая может быть интерпретирована в дальнейшем как пустая строка.

Option explicit

    '// Define the blue color here
    dim ibluecolor: ibluecolor = 15652797 ' this is 40% Accent1

    msgbox "starting"
    call xlsToCsv()
    msgbox "finished"


Public Sub xlsToCsv()    
    Const WorkingDir = "C:\Test\"
    Const xlCSV = 24
    Const xlUp = -4162

    Dim fso, SaveName, myFile, myFolder
    Dim objExcel, objWorkbook, wsSource, wsTarget
    Dim oOutputFile

    myFile = "source_file.xlsx"
    SaveName = "test2.csv"


    With CreateObject("Scripting.FilesystemObject")
        '// Check that the input file exists
        If Not .FileExists(WorkingDir & myFile) Then
            MsgBox "File not found:" & vbCrLf & WorkingDir & myFile, vbInformation, "Script Cancelled"
            WScript.Quit
        End If


        '// Create a text file to be the output csv file
        '//                                             Overwrite v     v False=ASCII format use True for Unicode format
        set oOutputFile = .CreateTextFile( WorkingDir & SaveName, True, False) 


    End With


    Set objExcel = CreateObject("Excel.Application")
    objExcel.Visible = False
    objExcel.DisplayAlerts = False


    Set objWorkbook = objExcel.Workbooks.Open(WorkingDir & myFile)
    Set wsSource = objWorkbook.Sheets(1)

    oOutputFile.WriteLine """ID"",""NAME"",""DESC"""

    '// Get the three column ranges, starting at cells in row 7
    dim Fcol, Acol, Ecol
    With wsSource
        set Fcol = .Range("F7", .Range("F" & .Rows.Count).End(xlUp))
        set Acol = .Range("A7", .Range("A" & .Rows.Count).End(xlUp))
        set Ecol = .Range("E7", .Range("E" & .Rows.Count).End(xlUp))
    End With

    '// Get the number of rows in each column
    dim Frc, Arc, Erc
    Frc = Fcol.Rows.Count
    Arc = Acol.Rows.Count
    Erc = Ecol.Rows.Count

    '// Rowcount is the max row of the three
    dim rowcount
    rowcount = Max(Arc, Frc, Erc)

    dim AVal, FVal, EVal

    dim ix
    for ix = 1 to rowcount
        '// Note - row 1 of each column is actually row 7 in the workbook
        AVal = REPLACE(ACol.Cells(ix, 1), """", """""")
        EVal = REPLACE(ECol.Cells(ix, 1), """", """""")
        FVal = REPLACE(FCol.Cells(ix, 1), """", """""")

        '// Check for an empty row
        if Len(AVal)=0 and len(EVal)=0 and len(FVal)=0 then
            '// skip this row

        '// Check for a blue row
         elseif ACol.cells(ix,1).Interior.Color = iBlueColor then
            '// skip this row

        else 
            '// Write the line to the csv file
            oOutputFile.WriteLine """" & FVal & """,""" & AVal & """,""" & EVal & """"

        end if
    next

    '// Close the output file
    oOutputFile.Close

    '// Close the workbook
    objWorkbook.Close True
    objExcel.Quit

    '// Clean up
    Set oOutputFile = Nothing
    Set objWorkbook = Nothing
    Set objExcel = Nothing
    Set fso = Nothing
    Set myFolder = Nothing

End Sub

Function Max(v1, v2, v3)
    select case true
    case v1 >= v2 and v1 >= v3
        Max = v1
    case v2 >= v3
        Max = v2
    case else
        Max = v3
    end select
end function
person JohnRC    schedule 24.10.2017

person    schedule
comment
этот файл excel имеет 1400 строк. Ваше решение работает, но для завершения требуется около 6 минут. Вы знаете что-то быстрее? - person nolags; 23.10.2017
comment
Попробуйте поставить Appplication.Calculation=xlCalculationManual и Application.Screenupdating=False перед циклом, а затем сбросить их на xlCalculationAutomatic и True после цикла. - person JohnRC; 23.10.2017
comment
Извините, в моем примечании выше должно было быть сказано ObjExcel вместо Application - я думаю, это то, что вы пытались? - person JohnRC; 24.10.2017
comment
я уже изменил его на objExcel, потому что с приложением это не сработало. Но это все равно длится около 6 минут.. это общее время что-то вроде этого длится или есть более быстрый способ - person nolags; 24.10.2017