2017-01-03 483 views
0

我需要将许多excel文件编译到一个excel文件中,然后将编译后的文件复制到现有的excel文件中(使用宏/ .xlsm)在某张纸上。Python pandas将结果数据框写入xlsm而不会丢失宏

我解决了第一个问题(将多个excel文件编译成一个excel文件)。结果数据框以.csv格式保存。结果文件看起来像这样。 the resulted dataframe

直到这里没有问题。下一步,我正在努力寻找如何去做。

从结果数据框中,我希望将数据框“复制并粘贴”到相应标题的工作表“Source”中的宏(.xlsm)的现有excel文件中。现有的Excel文件看起来像这样。 target excel file

从上面的图片可以看出,我想跳过在列A中写入任何数据,因为此列中的单元格满了公式。我想在现有的Excel文件中将列B中的结果数据框写入Q列。但是,在写入数据之前,我想删除所有单元格中的所有现有数据(A列中的单元格除外)。

所以基本上我要做到以下几点:

  1. 删除单元中的所有值列B到Q列在 现有XLSM文件(在片“源代码”)
  2. 写在导致数据帧到b列的新值,直到Q列
  3. 保存Excel文件后面的同名不失宏观

任何反馈将b非常感谢!谢谢!

问候,

阿诺德

+0

开始录制宏,而这样做你列出的操作。然后拿出它的结果代码并进行处理。 – user3598756

+0

基本上,我从你的问题中了解到,你想在数据框中将列B中的值替换为Q? 如果是这种情况,那么您可以使用'df.drop()'并通过'df [] = ' –

+0

@ user3598756添加新列谢谢您的评论。但是,我不是一个非常精明的人,所以我不完全理解你的建议。似乎您建议手动处理复制和粘贴数据。虽然我试图自动化我的编译工作。尽管如此,谢谢你的建议! – arnold

回答

0

对不起有点晚回来更新我的问题。最后,我用openpyxl软件包解决了我的问题。

因此,这里是我的最终代码:

import openpyxl 
import os 
import string 
import pandas as pd 
import numpy as np 

path = #folder directory 
target_file = #excel filename 
sheetname = #working sheet that you wish to work on with 

filename = os.path.join(path, target_file) 

wb = openpyxl.load_workbook(filename, keep_vba=True) 
sheet = wb.get_sheet_by_name(sheetname) 

# To Erase All Values within Selected Columns 
d = dict() 
for x, y in zip(range(1, 27), string.ascii_lowercase): 
    d[x] = y.upper() 

max_row = sheet.max_row 
max_col = sheet.max_column 

for row in range(max_row): 
    row += 1 
    if row == 1: continue 
    for col in range(max_col): 
     col += 1 
     if col == 1: continue 
     sheet['{}{}'.format(d[col], row)] = None 

# To Write Values to the Blank Worksheet 
path_dataframe = # folder directory to the csv file 
target_compiled = # csv filename 
filename_compiled = os.path.join(path_compiled, target_compiled) 

compiled = pd.read_csv(filename_compiled, low_memory=False, encoding = "ISO-8859-1") 

for row in range(len(compiled.index)): 
    row += 1 
    if row == 1: continue # I do not want to change the value in row 1 in excel file because they are headers 
    for col in range(max_col): 
     col += 1 
     if col == 1: continue # I do not want to change the values in column 1 in excel file since they contain formula 
     value = compiled.iloc[row-2][col-2] 
     if type(value) is str: value = value 
     elif type(value) is np.float64: value = float(value) 
     elif type(value) is np.int64: value = int(value) 
     sheet['{}{}'.format(d[col], row)] = value 

wb.save(filename) 
0

由于您的CSV导入到电子表格可以使用Excel VBA宏使用QueryTables考虑有Python的复制VBA与COM接口,Excel对象库来处理。之前的所有宏代码保持不变,因为没有被覆盖,但是单元数据。 注意:下面假定您正在使用Excel for Windows。

使用win32com库,Python几乎可以复制VBA所做的任何事情。事实上,您将会知道VBA是Office应用程序中的附加参考,并且绝不会是本机内置对象,并且会执行相同的COM接口!在您的IDE中查看Tools\References中的第一个选定项目。

import pandas as pd 
import win32com.client as win32 

# ...same pandas code...  
macrofile = "C:\\Path\\To\\Macro\\Workbook.xlsm" 
strfile = "C:\\Path\\To\\CSV\\Output.csv" 
df.to_csv(strfile) 

try: 
    xl = win32.gencache.EnsureDispatch('Excel.Application') 
    wb = xl.Workbooks.Open(macrofile) 

    # DELETE PREVIOUS DATA 
    wb.Sheets("Source").Range("B:Q").EntireColumn.Delete() 

    # ADD QUERYTABLE (SPECIFYING DESTINATION CELL START) 
    qt = wb.Sheets("Source").QueryTables.Add(Connection="TEXT;" + strfile, 
              Destination=wb.Sheets(1).Cells(2, 2)) 
    qt.TextFileParseType = 1 
    qt.TextFileConsecutiveDelimiter = False 
    qt.TextFileTabDelimiter = False 
    qt.TextFileSemicolonDelimiter = False 
    qt.TextFileCommaDelimiter = True 
    qt.TextFileSpaceDelimiter = False 
    qt.Refresh(BackgroundQuery=False) 

    # REMOVE QUERYTABLE 
    for qt in wb.Sheets("Source").QueryTables: 
     qt.Delete() 

    # CLOSES WORKBOOK AND SAVES CHANGES 
    wb.Close(True) 

except Exception as e: 
    print(e) 

finally:  
    qt = None 
    wb = None 
    xl = None 

可替代地,创建在VBA一个新的宏(置于一个独立的模块中),并且具有的Python调用它,传递csv文件路径作为参数:

VBA

Public Sub ImportCSV(strfile As String) 
    Dim qt As QueryTable 

    ThisWorkbook.Sheets("Source").Range("B:Q").EntireColumn.Delete 

    ' ADD QUERYTABLE 
    With ThisWorkbook.Sheets("Source").QueryTables.Add(Connection:="TEXT;" & strfile, _ 
     Destination:=ThisWorkbook.Sheets(1).Cells(2, 2)) 
      .TextFileParseType = xlDelimited 
      .TextFileConsecutiveDelimiter = False 
      .TextFileTabDelimiter = False 
      .TextFileSemicolonDelimiter = False 
      .TextFileCommaDelimiter = True 
      .TextFileSpaceDelimiter = False 

      .Refresh BackgroundQuery:=False 
    End With 

    ' REMOVE QUERYTABLE 
    For Each qt In ThisWorkbook.Sheets(1).QueryTables 
     qt.Delete 
    Next qt 

    Set qt = Nothing 
End Sub 

Python

import pandas as pd 
import win32com.client as win32 

# ...same pandas code...  
macrofile = "C:\\Path\\To\\Macro\\Workbook.xlsm" 
strfile = "C:\\Path\\To\\CSV\\Output.csv" 
df.to_csv(strfile) 

try: 
    xl = win32.gencache.EnsureDispatch('Excel.Application') 

    wb = xl.Workbooks.Open(macrofile) 
    xl.Application.Run('ImportCSV', strfile) 

    wb.Close(True) 
    xl.Quit 

except Exception as e: 
    print(e) 

finally:  
    wb = None 
    xl = None 
+0

感谢您的解释!一旦我得到结果,我会尽力回来!感谢您花时间和精力解决我的问题! – arnold

相关问题