<i id='NPkLL'><tr id='NPkLL'><dt id='NPkLL'><q id='NPkLL'><span id='NPkLL'><b id='NPkLL'><form id='NPkLL'><ins id='NPkLL'></ins><ul id='NPkLL'></ul><sub id='NPkLL'></sub></form><legend id='NPkLL'></legend><bdo id='NPkLL'><pre id='NPkLL'><center id='NPkLL'></center></pre></bdo></b><th id='NPkLL'></th></span></q></dt></tr></i><div id='NPkLL'><tfoot id='NPkLL'></tfoot><dl id='NPkLL'><fieldset id='NPkLL'></fieldset></dl></div>

  1. <legend id='NPkLL'><style id='NPkLL'><dir id='NPkLL'><q id='NPkLL'></q></dir></style></legend>
  2. <tfoot id='NPkLL'></tfoot>

    <small id='NPkLL'></small><noframes id='NPkLL'>

      <bdo id='NPkLL'></bdo><ul id='NPkLL'></ul>

      使用 Python 和 comtypes 使用数组设置 Excel 范围?

      Setting an Excel Range with an Array using Python and comtypes?(使用 Python 和 comtypes 使用数组设置 Excel 范围?)
      • <bdo id='Kwecf'></bdo><ul id='Kwecf'></ul>
          • <small id='Kwecf'></small><noframes id='Kwecf'>

          • <legend id='Kwecf'><style id='Kwecf'><dir id='Kwecf'><q id='Kwecf'></q></dir></style></legend>

            <tfoot id='Kwecf'></tfoot>

              <i id='Kwecf'><tr id='Kwecf'><dt id='Kwecf'><q id='Kwecf'><span id='Kwecf'><b id='Kwecf'><form id='Kwecf'><ins id='Kwecf'></ins><ul id='Kwecf'></ul><sub id='Kwecf'></sub></form><legend id='Kwecf'></legend><bdo id='Kwecf'><pre id='Kwecf'><center id='Kwecf'></center></pre></bdo></b><th id='Kwecf'></th></span></q></dt></tr></i><div id='Kwecf'><tfoot id='Kwecf'></tfoot><dl id='Kwecf'><fieldset id='Kwecf'></fieldset></dl></div>
                  <tbody id='Kwecf'></tbody>
                本文介绍了使用 Python 和 comtypes 使用数组设置 Excel 范围?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                问题描述

                使用comtypes来驱动Python,它似乎在幕后发生了一些魔法,它没有将元组和列表转换为 VARIANT 类型:

                # RANGE("C14:D21") has values
                # Setting the Value on the Range with a Variant should work, but
                # list or tuple is not getting converted properly it seems
                
                >>>from comtypes.client import CreateObject
                >>>xl = CreateObject("Excel.application")
                >>>xl.Workbooks.Open(r'C:	empmy_file.xlsx')
                >>>xl.Visible = True
                >>>vals=tuple([(x,y) for x,y in zip('abcdefgh',xrange(8))])
                # creates: 
                #(('a', 0), ('b', 1), ('c', 2), ('d', 3), ('e', 4), ('f', 5), ('g', 6), ('h', 7))
                >>>sheet = xl.Workbooks[1].Sheets["Sheet1"]
                >>>sheet.Range["C14","D21"].Value()
                (('foo',1),('foo',2),('foo',3),('foo',4),('foo',6),('foo',6),('foo',7),('foo',8))
                >>>sheet.Range["C14","D21"].Value[()] = vals
                # no error, this blanks out the cells in the Range
                

                根据comtypes docs:

                当您将简单序列(列表或元组)作为 VARIANT 传递时参数,COM服务器将收到一个 VARIANT,其中包含 VARIANTSAFEARRAY,其中类型代码 VT_ARRAY |VT_VARIANT.

                When you pass simple sequences (lists or tuples) as VARIANT parameters, the COM server will receive a VARIANT containing a SAFEARRAY of VARIANTs with the typecode VT_ARRAY | VT_VARIANT.

                这似乎与 MSDN 所说的内容一致 关于将数组传递给 Range 的值.我还发现 this page 在 C# 中显示了类似的内容.谁能告诉我我做错了什么?

                This seems to be inline with what MSDN says about passing an array to a Range's Value. I also found this page showing something similar in C#. Can anybody tell me what I'm doing wrong?

                编辑

                我想出了一个更简单的例子,它执行相同的方式(因为它不起作用):

                I've come up with a simpler example that performs the same way (in that, it does not work):

                >>>from comtypes.client import CreateObject
                >>>xl = CreateObject("Excel.application")
                >>>xl.Workbooks.Add()
                >>>sheet = xl.Workbooks[1].Sheets["Sheet1"]
                # at this point, I manually typed into the range A1:B3
                >>> sheet.Range("A1","B3").Value()
                ((u'AAA', 1.0), (u'BBB', 2.0), (u'CCC', 3.0))
                >>>sheet.Range("A1","B3").Value[()] = [(x,y) for x,y in zip('xyz',xrange(3))]
                # Using a generator expression, per @Mike's comment
                # However, this still blanks out my range :(
                

                推荐答案

                我花了很多时间试图找出解决这个问题的办法,以便能够完全用 python 代替 matlab,在各种不同的论坛上阅读没有真正的直接答案.

                I've spent a lot of time trying to figure out a solution to this problem to be able to fully substitute python for matlab, reading on various different forums with no real direct answer.

                这是我运行良好的强大解决方案.我必须编写每天/每周/每月/每季度的报告,这些报告经常写入 xlsx,这个功能比他们使用 python & 写入 xlsx 的一些信息要好得多.com.

                Here is my robust solution that works very well. I have to write daily/weekly/monthly/quarterly reports that write to xlsx a lot, this function works much better than some of the information out their about writing to xlsx using python & com.

                from numpy import *
                from win32com.client import DispatchEx
                # DispatchEx opens up an independent instance of Excel so writing to a document won't interfere with any other instances you have running
                def xlsxwrite(filename, sheet, data, cellstr, screenupdating = False, direction = 'h', visible = 0):
                '''
                Write to an excel document by setting ranges equal to arrays.
                '''
                xl = DispatchEx("Excel.Application")
                xl.ScreenUpdating = screenupdating
                xl.Visible = visible
                try:
                  excel_type = get_exceltype(filename)
                  # Check to see if workbook exists, if it doesn't create workbook
                  try:
                      xlBook = xl.Workbooks.Open(filename)
                  except:
                      print '
                File Doesnt Exist, Writing File...
                
                
                '
                      xlBook = xl.Workbooks.Add()
                      try:
                          xlBook.SaveAs(filename, excel_type)
                      except:
                          xl.Quit()
                          raise NameError('Error writing file: %s, check to make sure path exists' % filename)
                  # Get wksht names
                  wksht_names = [xlBook.Sheets(i).Name for i in range(1,xlBook.Sheets.Count+1)]
                  # If 'sheet' variable is an integer, get sheet by index number, else get it by name, or add new one
                  try:
                      int(sheet)
                      try:
                          xlSheet = xlBook.Sheets(int(sheet))
                      except:
                          raise NameError('Error, referencing an invalid sheet')
                  except:
                      # If sheet input not in wksht names, add it
                      if sheet not in wksht_names:
                          print 'Worksheet, "%s", not found, Adding Worksheet' % sheet
                          xlBook.Sheets.Add(After=xlBook.Sheets(xlBook.Sheets.Count)).Name = sheet
                      xlSheet = xlBook.Sheets(sheet)
                  # Convert Excel Range to Python Range
                  row,col = getcell(cellstr)
                  # Write out data
                  output_dict, shp = data_export_cleaner(data, direction)
                  a,b = shp
                  start_cells = [(row,col+i) for i in range(b)]
                  end_cells = [(row + a -1,col+i) for i in range(b)]
                  for i in output_dict.keys():
                      cell_range = eval('xlSheet.Range(xlSheet.Cells%s,xlSheet.Cells%s)' %   (start_cells[i],end_cells[i]))
                      cell_range.Value = output_dict[i]
                  # Save and close document, Quit Excel App
                  xlBook.Close(True)
                  xl.Quit()
                  return
                  except:
                    xlBook.Close(False)
                    xl.Quit()
                    raise NameError('Error occurred while trying to write file')
                
                def data_export_cleaner(data,direction):
                  """
                  Summary: Return data in a format that works with Excel Com (Numpy int32 for some reason was causing an error, have to turn it into a string, doesn't affect any formatting possibilities).
                  Defaults: Going to set the default for writing data with len(shape(array(data))) == 1, such as a list, to horizontal, if you want to write it vertically, specify 'v', only applicable for lists.
                  """
                  darray = array(data)
                  shp = shape(darray)
                  if len(shp) == 0:
                      darray = array([data])
                      darray = darray.reshape(1,1)
                  if len(shp) == 1:
                      darray = array([data])
                      if direction.lower() == 'v':
                          darray = darray.transpose()
                  shp = shape(darray)
                  tempdict = dict()
                  for i in range(shp[1]):
                      tempdict[i] = [(str(darray[j,i]),) for j in range(shp[0])]
                  return tempdict, shp
                
                
                def get_exceltype(filename):
                  format_dict = {'xlsx':51,'xlsm':52,'xlsb':50,'xls':56}
                  temp = character_count(filename)
                  if (temp['.'] > 1 or temp['.'] == 0):
                      raise NameError('Error: Incorrect File Path Name, multiple or no periods')
                  f_type = filename.split('.')
                  f_type = f_type[len(f_type)-1]
                  if f_type not in format_dict.keys():
                      raise NameError('Error: Incorrect File Path, No excel file specified')
                  else:
                      return format_dict[f_type]
                
                
                def character_count(a_string):
                  temp = dict()
                  for c in a_string:
                      temp[c] = temp.get(c,0) + 1
                  return temp
                
                
                
                def getcell(cell):
                  '''Take a cell such as 'A1' and return the corresponding numerical row and column in excel'''
                  a = len(cell)
                  temp_column = []
                  row = []
                  temp_row = []
                  if a < 2:
                      raise NameError('Error, the cell you entered is not valid')
                  for i in range(a):
                      if str.isdigit(cell[i])==False:
                          temp_column.append(cell[i])
                      else:
                          temp_row.append(cell[i])
                  row.append(string.join(temp_row,''))
                  row = int(row[0])
                  column = getnumericalcolumn(temp_column)
                  return row, column
                
                
                def getnumericalcolumn(column):
                  '''Take an excel column specification such as 'A' and return its numerical equivalent in excel'''
                  alpha = str(string.ascii_uppercase)
                  alphadict = dict(zip(alpha,range(1,len(alpha)+1)))
                  if len(column) == 1:
                      numcol = alphadict[column[0]]
                  elif len(column) == 2:
                      numcol = alphadict[column[0]]*26 + alphadict[column[1]]
                  elif len(column) == 3:
                      numcol = 26**2 + alphadict[column[1]]*26 + alphadict[column[2]]
                  return numcol
                

                注意事项:我经常使用 Numpy,因为它对于以我想要编写的格式创建表非常有用,因此这是以下函数工作所需的库.我知道所有这些函数都可以组合起来创建一个类,但是因为这个函数是在脚本中调用的,而且它们对于将它创建为一个类并没有真正的好处,所以我没有这样做.

                Notes: I use Numpy a lot because it is very useful for creating the tables in the format I want to write them, so that is a required library for the below functions to work. I know all these functions could combined to create a class, but because this function is called in a script and their isn't really a significant benefit to creating it as a class, I haven't done so.

                这篇关于使用 Python 和 comtypes 使用数组设置 Excel 范围?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                相关文档推荐

                What happens when you compare 2 pandas Series(当你比较 2 个 pandas 系列时会发生什么)
                Quickly find differences between two large text files(快速查找两个大文本文件之间的差异)
                Python - Compare 2 files and output differences(Python - 比较 2 个文件和输出差异)
                Why do comparisions between very large float values fail in python?(为什么在 python 中非常大的浮点值之间的比较会失败?)
                Dictionary merge by updating but not overwriting if value exists(字典通过更新合并,但如果值存在则不覆盖)
                Find entries of one text file in another file in python(在python中的另一个文件中查找一个文本文件的条目)

                • <i id='9s9MI'><tr id='9s9MI'><dt id='9s9MI'><q id='9s9MI'><span id='9s9MI'><b id='9s9MI'><form id='9s9MI'><ins id='9s9MI'></ins><ul id='9s9MI'></ul><sub id='9s9MI'></sub></form><legend id='9s9MI'></legend><bdo id='9s9MI'><pre id='9s9MI'><center id='9s9MI'></center></pre></bdo></b><th id='9s9MI'></th></span></q></dt></tr></i><div id='9s9MI'><tfoot id='9s9MI'></tfoot><dl id='9s9MI'><fieldset id='9s9MI'></fieldset></dl></div>
                  <tfoot id='9s9MI'></tfoot>
                      <tbody id='9s9MI'></tbody>

                      <small id='9s9MI'></small><noframes id='9s9MI'>

                      • <bdo id='9s9MI'></bdo><ul id='9s9MI'></ul>
                        1. <legend id='9s9MI'><style id='9s9MI'><dir id='9s9MI'><q id='9s9MI'></q></dir></style></legend>