1

列Aにキーワードのリストを含むExcelファイルがあります。

eg. Bob
    Dan
    Brian

列Bには、セルに複数のエントリがあるいくつかの行があります。

B1= Bob, Grant, James, Dave
B2= Dean, Dan, Brian

列Cと、列AとセルBにある名前をどのように出力しますか。つまり、次のような出力が必要です。

C1= Bob
C2= Dan, Brian

何か案は?Pythonを使用してみましたが、開始方法がわかりません。

助けていただければ幸いです

4

2 に答える 2

1

まず、Excelへのアクセスに使用しているPythonモジュールによって異なります。Windowsを使用している場合は、ここにあるWin32Comを使用することをお勧めします。このモジュールは、Pythonで任意のMicrosoft Officeアプリケーション(Excelを含む)にプログラムでアクセスできるようにし、VBAで使用されているものと同じ方法の多くを使用します。

Win32ComforExcelを使用した場合の問題の解決策は次のとおりです。名前間の区切り文字としてコンマ('、')を使用しており、列Aと列Bの間の名前の一致では大文字と小文字が区別されると想定しています(Pythonでは「A」は「a」と等しくないことに注意してください)。

まず、Excelに接続して、自分の名前でシートにアクセスします。

#First we need to access the module that lets us connect to Excel
import win32com.client 

# Next we want to create a variable that represents Excel
app = win32com.client.Dispatch("Excel.Application")   

# Lastly we will assume that the sheet with the names is the active sheet
sheet = app.ActiveSheet

この時点で、アクティブなExcelワークシートを名前で表すsheetという名前の変数があります。セルをクリックするだけでシートをアクティブ化できます。次に、列Aのすべての名前を取得し、それをリストに保存することから始めます。これを行うには、次の2つのオプションがあります。

  1. 列Aのすべてのセルを反復処理し、文字列として格納されている名前を抽出し、sheet.Cells(row、col).Valueを使用してすべての名前のリストに追加できます。これは、範囲が狭い場合は問題なく機能しますが、500行以上を処理している場合は遅くなる可能性があります。
  2. sheet.Range( "A1"、 "A3")。Valueを使用して、名前を含む列Aのセルの全範囲を抽出し 、値をリストに追加できます。セルの範囲が広い場合、これははるかに高速になります。この例では、Rangeを使用します。

続く例:

import win32com.client
app = win32com.client.Dispatch("Excel.Application")   
sheet = app.ActiveSheet

# rang is an object representing the cells A1, A2, A3
rang = sheet.Range("A1","A3")

# names is a tuple of length 3 containing tuples of length 2
names = rang.Value

#nameLst is a list of all values in names
nameLst = [name[0] for name in names]

次に、列Bのすべての名前を繰り返し処理します。このために、sheet.Cells.Value関数を使用して、列Bの各セルの名前のリストを取得します。文字列も使用します。 split( "、")関数を使用して、コンマ区切りの名前を名前のリストに分割し、string.strip()を使用して不要な空白を削除します。このリストの名前のいずれかがnameLstにある場合、一致するものがあることがわかり、それを列Cに配置します。

import win32com.client
app = win32com.client.Dispatch("Excel.Application")   
sheet = app.ActiveSheet

rang = sheet.Range("A1","A3")
names = rang.Value
nameLst = [name[0] for name in names]

#Iterate over the rows ic ColB. Remember Excel uses base 1 not 0 for inexing
for rowI in range(1,3):
    cellNames = sheet.Cells(rowI,2).Value

    #split cellNames by "," and add all of the names to a list.
    cellNamesLst = [cellName.strip() for cellName in cellNames.split(",")]

    #Now we want a list of all names that are in cellNamesLst and in nameLst
    matchLst = [matchName for matchName in cellNamesLst if matchName in nameLst]

    #Create a string of all matches to go in Col C
    allMatches = ", ".join(matchLst)

    #Lastly put all matches in in Col C
    sheet.Cells(rowI,3).Value = allMatches

これにより、文字列「Bob」がセルC1に配置され、「Dan、Brian」がセルC2に配置されます。win32comの使用は非常に強力であり、すべてのMSOfficeアプリケーションで行うことの多くを自動化するために使用できます。

コメントなしの最終コードは次のとおりです。

import win32com.client
app = win32com.client.Dispatch("Excel.Application")   
sheet = app.ActiveSheet

rang = sheet.Range("A1","A3")
names = rang.Value
nameLst = [name[0] for name in names]

for rowI in range(1,3):
    cellNames = sheet.Cells(rowI,2).Value
    cellNamesLst = [cellName.strip() for cellName in cellNames.split(",")]
    matchLst = [matchName for matchName in cellNamesLst if matchName in nameLst]
    allMatches = ", ".join(matchLst)
    sheet.Cells(rowI,3).Value = allMatches

お役に立てれば。

于 2012-08-13T16:13:20.817 に答える
0

私が見ているように、「列」とその「セル」は単なるリストです。

#the "columns"

A = ["Bob","Dan","Brian"]
B = [["Bob", "Grant", "James", "Dave"],\
     ["Dean", "Dan", "Brian"]]
C = []


for b in B:
    c = []
    for name in b:
        if name in A:
            c.append(name)
    C.append(c)

for c in C:
    print c

>>> 
['Bob']
['Dan', 'Brian']

あなたがする必要があるのは、各列をリストに読み込むことだけです。列Aの場合、名前のリストとして項目を追加するだけです。列Bの場合は、各セルを独自のリストとしてメインリストに追加するだけです。

そして、あなたはそれを持っています。

于 2012-08-13T12:38:32.317 に答える