Excelでは、my UDFが255文字を超える文字列を返したときにExcelが#VALUE!
と表示されます。excelセルに> 255文字を表示する
xlwingsは0.7.1です.Excelは2007年で、マイクロソフトのように、セルに32767文字まで使用できます。
どこが問題なのですか?
Excelでは、my UDFが255文字を超える文字列を返したときにExcelが#VALUE!
と表示されます。excelセルに> 255文字を表示する
xlwingsは0.7.1です.Excelは2007年で、マイクロソフトのように、セルに32767文字まで使用できます。
どこが問題なのですか?
私が知る限り、Py.CallUDF(xlwings udfsで使用)は2Dバリアント配列を返します。
純粋なVBA UDFから255より大きい文字列長のVariant配列を返すことによって、Excelで呼び出されたときに#VALUEエラーが発生することもあります。 VBAエディタの配列に時計を置くと、データがそのまま残っていることがわかります。正しく渡されていないだけです。少しの検索でVBAの文字列の長さが最大限に近づくにつれていくつかの質問が返されましたが、
リターン文字列配列または255文字を超える単一の文字列は正常に動作するようです。ここで
問題を示すいくつかの純粋なVBAの例です:
戻りバリアント配列:
Function variant_long_string(n)
Dim temp(0 To 0, 0 To 0) As Variant
temp(0, 0) = String(n, "a")
variant_long_string = temp
End Function
エクセル、リターン(Nのために失敗した> 255)からの呼び出し:
255 aaaaaaaaaaaaa....aaaaaaaaa
256 #VALUE!
バリアント配列の戻り要素:
Excelから呼び出すFunction variant_long_string_element(n)
Dim temp(0 To 0, 0 To 0) As Variant
temp(0, 0) = String(n, "a")
variant_long_string_element = temp(0, 0)
End Function
、リターン(> 255 Nのために成功した):
255 aaaaaaaaaaaaa....aaaaaaaaa
256 aaaaaaaaaaaaa....aaaaaaaaaa
戻り文字列配列:エクセル、リターン(Nのために成功した> 255から呼び出す
Function string_long_string(n)
Dim temp(0 To 0, 0 To 0) As String
temp(0, 0) = String(n, "a")
string_long_string = temp
End Function
):
255 aaaaaaaaaaaaa....aaaaaaaaa
256 aaaaaaaaaaaaa....aaaaaaaaaa
回避策
あなたのpython UDFは、このように、単一の文字列値を返す場合:
@xw.func
def build_long_string(n):
res = 'a'*int(n)
return res
xlwingsはxlwings_udfsのモジュールに次のVBAマクロを自動生成します:速いよう
Function build_long_string(n)
If TypeOf Application.Caller Is Range Then On Error GoTo failed
build_long_string = Py.CallUDF(PyScriptPath, "build_long_string", Array(n), ThisWorkbook)
Exit Function
failed:
build_long_string = Err.Description
End Function
をパッチを適用してUDFを動作させ、そのマクロを少し変更してください:
Function build_long_string(n)
If TypeOf Application.Caller Is Range Then On Error GoTo failed
temp = Py.CallUDF(PyScriptPath, "build_long_string", Array(n), ThisWorkbook)
build_long_string = temp(0, 0)
Exit Function
failed:
build_long_string = Err.Description
End Function
は、255文字を超える文字列をExcelに正常に反映させます。あなたは配列の結果に似たようなことをすることができます。ただ、tempからその結果までのすべての値をループ/再割り当てすることによって、Variant配列をString配列に変換するだけです。
は、2D文字列配列に2次元バリアント配列を変換する上記の@ schoolieの提案に基づいて、私は私のローカルxlwingsでVBA関数生成ロジックのソース修飾:(udfs.generate_vba_wrapperで
)を
置き換えます。
vba.write('r = Py.CallUDF("{module_name}", "{fname}", {args_vba}, ThisWorkbook)\n',
module_name=module_name,
fname=fname,
args_vba=args_vba,
)
vba.write('ReDim strarray(UBound(r, 1), UBound(r, 2)) As String\n')
vba.write('For i = 0 To UBound(r, 1)\n')
vba.write(' For j = 0 To UBound(r, 2)\n')
vba.write(' strarray(i, j) = CStr(r(i, j))\n')
vba.write(' Next\n')
vba.write('Next\n')
vba.write('{fname} = strarray\n', fname=fname)
のTh:と
vba.write('{fname} = Py.CallUDF("{module_name}", "{fname}", {args_vba}, ThisWorkbook)\n',
module_name=module_name,
fname=fname,
args_vba=args_vba,
)
他のオプションは、 'Import Python UDFs'を実行した後に、VBエディタで生成されたVBマクロをパッチすることです。しかし、この変更は再インポートすると失われます。コードはすでに上記の@schoolieで与えられています
上記の詳細な説明と回避策は非常に役に立ちます。私のUDFはほとんどが文字列を返すので、String 2D配列に変換すると私にとってうまくいきます。私は変更を加えました。VBA関数(import_udfs.py)を書き込むコードを変更することで回避策を修正しました。そうすれば、私はudfsの再インポート後に編集内容を失うことはありません。 – Jorge
参考のために、xlwings githubページの[link](https://github.com/ZoomerAnalytics/xlwings/issues/456)に問題がありました。 – schoolie