2017-07-20 235 views
0

私は、特定の行でExcelスプレッドシートをソートするためにpythonを使用する必要があります。テストのために、私は(という名前のファイルxlwingsでsorting.xlsx)このデータを使用しています:一つは、これは些細なことと思うだろうxlwings(pywin32)でソートする

Numbers Letters Letters_2 
1 G H 
2 F I 
3 E N 
4 D J 
5 C M 
6 B K 
7 A L 

:これに分類されなければならない

Numbers Letters Letters_2 
7 A L 
6 B K 
5 C M 
4 D J 
3 E N 
2 F I 
1 G H 

を(もし何かがあれば2日の読書でそれが明らかにされていないほど深く埋まっています)xlwings文書またはpywin32のいずれかで列の並べ替えに関しては何も書かれていません。

私がどこでもオンラインで見つけることができる最も近いものは、回答がなく、解像度のないgithubバグスレッドにリダイレクトされるだけです。this questionです。

それでも、私は一緒質問者に基づいて、次のコードを考え出すために管理している:

import xlwings as xw 
from xlwings.constants import SortOrder 

bk = xw.Book(r'C:\Users\username\Documents\Test Files\xlwings sorting.xlsx') 

sht = bk.sheets['Sheet1'] 

def xl_col_sort(sht,col_num): 
    sht.range('a2').api.Sort(sht.range((2,col_num)).api,SortOrder.xlAscending) 
    return 

xl_col_sort(sht,1) 

これは動作しますが、私は、構文が機能しているか分かりません。最初のrange('a2')コールがなぜ必要なのかはわかりませんが、sht.api.Sortを直接呼び出すと例外がスローされます。私はipythonのコードを直接見てみましたか?それは私にdocstringのない<xlwings._xlwindows.COMRetryObjectWrapper object at 0x0000001375A459E8>を与えるだけです。私は実際にSort()関数の.pyファイルを使って実際にCtrl + Fキーを押してみましたが、巨大なCOMラッパーのリストに行き詰まり、関数を含む実際のモジュールを追跡できませんでした。

私は手がかりがない場合でも、テストケースが機能します。次のステップでは、この関数をメソッドとして使用するExcelワークブックとシートを含むクラスにこの関数を配置します。 (番号はしばしば変更しますので、新しい列が頻繁にワークシートの真ん中に追加されている)私は両方の方法として、代わりに列番号の文字列を取るために使用するコードを書き換える:

class Metrics: 

    # self.sheet is a sheet object based on self.book opened with xlwings 
    # a bunch of other methods and attributes 

    def xl_col_sort(self,col): 

     # +2 because excel starts at 1 (+1) and the dataframe self.df 
     # uses a data column as the index (+1) 
     col_num = np.where(self.df.columns == col)[0][0] + 2 

     so = xw.constants.SortOrder 

     self.sheet.range('a2').api.Sort(self.sheet.range((2,col_num)).api, so.xlAscending) 
     return 

私ができます」機能的に何かが変更されているのを見てください。それは、たとえ追加のステップを経て作成されたとしても、引き続き同じ議論を受けています。しかし、これはMemoryError生成し実行しようと:この事の構文がどのように機能するか

In[1]: metrics.xl_col_sort('Exp. Date') 
--------------------------------------------------------------------------- 
MemoryError        Traceback (most recent call last) 
<ipython-input-3-f1de8b0e8e98> in <module>() 
----> 1 metrics.xl_col_sort('Exp. Date') 

C:\Users\username\Documents\Projects\PyBev\pyBev_0-3-1\pybev\metricsobj.py in xl_col_sort(self, col) 
    146   so = xw.constants.SortOrder 
    147 
--> 148   self.sheet.range('a2').api.Sort(self.sheet.range((2,col_num)).api, so.xlAscending) 
    149   return 
    150  # def monday_backup(self): 
C:\Users\username\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\xlwings\main.py in range(self, cell1, cell2) 
    818     raise ValueError("Second range is not on this sheet") 
    819    cell2 = cell2.impl 
--> 820   return Range(impl=self.impl.range(cell1, cell2)) 
    821 
    822  @property 
C:\Users\username\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\xlwings\_xlwindows.py in range(self, arg1, arg2) 
    576    if 0 in arg1: 
    577     raise IndexError("Attempted to access 0-based Range. xlwings/Excel Ranges are 1-based.") 
--> 578    xl1 = self.xl.Cells(arg1[0], arg1[1]) 
    579   elif isinstance(arg1, numbers.Number) and isinstance(arg2, numbers.Number): 
    580    xl1 = self.xl.Cells(arg1, arg2) 
C:\Users\username\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\xlwings\_xlwindows.py in __call__(self, *args, **kwargs) 
    149   for i in range(N_COM_ATTEMPTS + 1): 
    150    try: 
--> 151     v = self._inner(*args, **kwargs) 
    152     t = type(v) 
    153     if t is CDispatch: 
C:\Users\username\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\win32com\client\dynamic.py in __call__(self, *args) 
    190     if invkind is not None: 
    191       allArgs = (dispid,LCID,invkind,1) + args 
--> 192       return self._get_good_object_(self._oleobj_.Invoke(*allArgs),self._olerepr_.defaultDispatchName,None) 
    193     raise TypeError("This dispatch object does not define a default method") 
    194 
MemoryError: CreatingSafeArray 

は誰もが知っていますかメソッド内に置くとき、なぜそれが壊すのか?

答えて

0

これは非常に微妙なエラーであることが判明したので、何か似たようなことをしようとしている1年のうちに誰かがこれをグーグルで見つけた場合に回答を投稿すると思いました。要するに

sheet.range()方法は、整数のみである座標を受け付け、式:

col_num = np.where(self.df.columns == col)[0][0] + 2 

は、浮動小数点数を生成します。構文エラーの代わりにMemoryErrorが生成されるのはなぜですか?しかし、おそらく監督です。実際にVBAコードであるためSort()方法のみRangeオブジェクト、従って第一sht.range()呼要求上で動作here.見られるようThe devs do seem to know about it, though.

さらに、構文は、前述のドキュメントに記載されていません。

そして最後に、ケースには誰もがすべてのこのナンセンスをカプセル化するために単純化された機能を望んでいる:

import xlwings as xw 


bk = xw.Book(file_path) 
sheet = bk.sheets['Sheet1'] # or whatever the sheet is named 

def xl_col_sort(sheet,col_num): 
    sheet.range((2,col_num)).api.Sort(Key1=sheet.range((2,col_num)).api, Order1=1) 
return 
関連する問題