R / vba - открыть и сохранить несколько книг (+500) и отбросить формулы, т.е. сохраняя только фрейм данных

Я хотел бы открыть несколько файлов книги (xlsx) с несколькими электронными таблицами, отбросить формулы в каждой ячейке и сохранить только данные внутри. Я бы сделал это вручную, но имея как минимум 500 рабочих тетрадей, я хотел бы автоматизировать задачу.

Я нашел себе несколько частичных решений. Возможно, самым простым было бы сделать это через vba, но я понятия не имею, как писать эти инструкции. Другие решения, которыми я мог бы управлять, были бы через R.

Я протестировал несколько пакетов, наиболее полезным из которых был xlsx, к сожалению, я могу сохранить только 1 электронную таблицу за раз, и у меня их более 15 на книгу, и я не нашел, как объединить каждую электронную таблицу в один файл (одну книгу).

Решение, которое я пришел до сих пор, - открыть файлы внутри цикла, а затем снова сохранить их с помощью XLConnect. Я искал формулу «запись без формулы», зная, что существует возможность «открыть без формулы», но мне не удалось найти вариант ... Есть ли простое решение с этими пакетами, или мне следует перейти на VBA?

ориентировочно в r:

library("XLConnect")
wbdir <- setwd("C:/Users/blabla/Desktop/wbfiles")
wblist <- list.files(wbdir)

i <- 0L
for (i in 1:length(wblist)) {

        wb_formulas <- loadWorkbook(wblist[[i]])
        # something to overwriteformulas : opening witout formulas like xlsx/openxlsx package 
        # writing without ...
        wb_df <- saveWorkbook(wb_formulas, paste(c("wb_", i,".xlsx"),collapse = ""))
}

person Ovidiu    schedule 24.10.2017    source источник
comment
VBA может легко это сделать, и вы также можете сделать это, не открывая документы. Excel может читать их как файлы, доступные только для чтения ... Я быстро выполнил поиск, и это отличный источник для начала encodedna.com/excel/   -  person Maldred    schedule 24.10.2017
comment
Я бы использовал vba. разбейте задачи на части. пролистайте книги, затем запустите функцию, которая открывает, копирует информацию, вставляет в другую книгу, а затем закрывает книгу с образцами. Хотя вы вполне могли бы использовать r.   -  person Preston    schedule 24.10.2017
comment
Пожалуйста, разместите код того, что вы уже пробовали   -  person Tom M    schedule 24.10.2017
comment
отредактировал отредактировал @Maldred, проверяя ссылки, я также попытаюсь проверить простой код VBA, если не смог избежать этой части   -  person Ovidiu    schedule 24.10.2017


Ответы (1)


Рассмотрим RDComclient R, который может COM интерфейс к библиотеке объектов Excel, где вы можете использовать R для циклического перебора необходимых файлов и соответствующих листов и использования собственных методов Excel (а не методов сторонних пакетов), Range.Copy и Range.PasteSpecial, чтобы копировать значения ячеек без формул.

Ниже процедура заключена в tryCatch, чтобы без проблем выйти из обработки даже с простыми ошибками. Обратите внимание: некоторые COMExceptions не перехватываются, и вам нужно будет выйти из процесса EXCEL.EXE из диспетчера задач.

library(RDCOMClient)

wbdir <- setwd("C:/Users/blabla/Desktop/wbfiles")
wblist <- list.files(wbdir, full.names = TRUE)

xlPasteValues <- -4163

for (wb in wblist) {    
  tryCatch({
    # Create COM Connection to Excel
    xlApp <- COMCreate("Excel.Application")
    xlApp[['Visible']] <- FALSE
    xlApp[['DisplayAlerts']] <- FALSE

    # Open workbook
    xlWB <- xlApp[["Workbooks"]]$Open(wb)

    # Iterate through each worksheet
    for (s in seq(xlWB$Worksheets()$Count())) {
      xlSheet <- xlWB$Worksheets(s)

      # Copy and paste values
      xlSheet$Cells()$Copy() 
      xlSheet$Cells()$PasteSpecial(xlPasteValues)

      xlApp[['CutCopyMode']] <- FALSE

      xlSheet$Activate()
      xlSheet$Range("A1")$Select()        
    }

    }, error=function(e) {
        print(e)  
    },

    finally={
      xlApp[['DisplayAlerts']] <- TRUE

      # Save Changes
      xlWB$Close(TRUE)        # THIS WILL OVERWRITE (BACKUP IN TEST MODE)
      xlApp$Quit()

      # Release resources
      xlSheet <- NULL
      xlWB <- NULL
      xlApp <- NULL

      rm(list=ls()) 
      gc()
    }
  )    
}

Поскольку COM - это технология Windows, указанное выше решение работает только в R, работающем в среде Windows.

person Parfait    schedule 24.10.2017
comment
Извините, нежелательное обновление ... Спасибо за этот код, Parfait, я постараюсь наверстать упущенное с пакетом RDComclient. Он работает довольно хорошо, тем не менее, у меня есть ошибка, и я не понимаю, почему она иногда появляется: сообщение из буфера обмена копирует / вставляет. Я искал, и он не должен появляться с xlApp [['cutcopymode']] ‹- Ложь. Я прав ? Нет, если клетки <100 - person Ovidiu; 26.10.2017
comment
Это не ошибка, а предупреждение пользователя от Excel о сумме, помещенной в буфер обмена. Он появляется с каждым файлом или только один раз? Консоль R выдает ошибку? - person Parfait; 26.10.2017
comment
Действительно появляется с каждым файлом и, кажется, также прерывает копирование. Консоль R показывает следующее: ‹simpleError в xlSheet $ Cells () $ PasteSpecial (xlPasteValues): объект 'xlPasteValues' не найден› - person Ovidiu; 27.10.2017
comment
См. Отключение / включение предупреждений об обновлении с помощью в Excel DisplayAlerts. И убедитесь, что у вас есть xlPasteValues ​​ (внешний цикл), назначенный, поскольку он есть в этом решении. - person Parfait; 27.10.2017
comment
Спасибо парфе. Теперь он работает. У меня все еще отображается сообщение об ошибке, но ваше последнее сообщение подсказывает мне, как ее исправить. Я положил xlPasteValues <- -4163 внутрь первого цикла. Я заметил, что переменные были стерты после первой итерации. Может быть, это была проблема, которая была у меня с самого начала. В любом случае код сейчас (если кому-то это тоже нужно): library(RDCOMClient) wbdir <- setwd("C:/Users/blabla/Desktop/wbfiles") wblist <- list.files(wbdir, full.names = TRUE) wblist xlPasteValues <- (-4163) for (wb in wblist) { xlPasteValues <- (-4163) - person Ovidiu; 30.10.2017