Calc(31)セルへ日付を入力する方法

2017-10-27

旧ブログ

t f B! P L
計算できる値としてセルに日付を入力する方法をやります。

前の関連記事:Calc(30)コンテクストメニューをカスタマイズする: その3


セルに日付を入力して書式設定をするマクロ

from com.sun.star.lang import Locale  # Struct
from com.sun.star.sheet import CellFlags  # 定数
from com.sun.star.util import NumberFormat  # 定数
global XSCRIPTCONTEXT
def macro():
 doc = XSCRIPTCONTEXT.getDocument()  # ドキュメントを取得。
 sheets = doc.getSheets()  # ドキュメントのシートコレクションを取得。。
 sheet = sheets[0]  # シートコレクションのインデックス0のシートを取得。
 sheet.clearContents(CellFlags.VALUE+CellFlags.DATETIME+CellFlags.STRING+CellFlags.ANNOTATION+CellFlags.FORMULA+CellFlags.HARDATTR+CellFlags.STYLES)  # セルの内容を削除。
 datestring = "2017-10-25"  # 2017-10-25 or 10/25/2017
 sheet["A1"].setString('sheet["B1"].setFormula("{}")'.format(datestring))
 sheet["B1"].setFormula(datestring)  # 式で日付を入力する。
 createFormatKey = formatkeyCreator(doc)
 formatstring = "YYYY-MM-DD"
 sheet["A2"].setString(formatstring)
 sheet["B2"].setFormula(datestring)
 sheet["B2"].setPropertyValue("NumberFormat", createFormatKey(formatstring))  # セルの書式を設定。 
 formatstring = "GE.MM.DD"
 sheet["A3"].setString(formatstring)
 sheet["B3"].setFormula(datestring)
 sheet["B3"].setPropertyValue("NumberFormat", createFormatKey(formatstring))  # セルの書式を設定。 
 sheet["A4"].setString("Standard Date Format")
 sheet["B4"].setFormula(datestring)
 numberformats = doc.getNumberFormats()
 formatkey =numberformats.getStandardFormat(NumberFormat.DATE, Locale())
 sheet["B4"].setPropertyValue("NumberFormat", formatkey)  # セルの書式を設定。 
 sheet["A:B"].getColumns().setPropertyValue("OptimalWidth", True)  # 列幅を最適化する。
def formatkeyCreator(doc):  # ドキュメントを引数にする。
 def createFormatKey(formatstring):  # formatstringの書式はLocalによって異なる。 
  numberformats = doc.getNumberFormats()  # ドキュメントのフォーマット一覧を取得。デフォルトのフォーマット一覧はCalcの書式→セル→数値でみれる。
  locale = Locale(Language="ja", Country="JP")  # フォーマット一覧をくくる言語と国を設定。インストールしていないUIの言語でもよい。。 
  formatkey = numberformats.queryKey(formatstring, locale, True)  # formatstringが既存のフォーマット一覧にあるか調べて取得。第3引数のブーリアンは意味はないはず。 
  if formatkey == -1:  # デフォルトのフォーマットにformatstringがないとき。
   formatkey = numberformats.addNew(formatstring, locale)  # フォーマット一覧に追加する。保存はドキュメントごと。 
  return formatkey
 return createFormatKey
g_exportedScripts = macro, #マクロセレクターに限定表示させる関数をタプルで指定。    
このマクロをCalcで実行すると次の結果が得られます。


日付はdate-time serial numberでセルに保持されている


式として2017-10-25を入力したB1セルには43033と表示されています。

式として入力できる形式は年/月/日のほか月/日/年ができましたが、これ以外の入力形式はわかりませんでした。

入力された日付はCalc固有のdate-time serial numberに変換されてセルに保持されます(日付と時刻関数 - LibreOffice Help, Documentation/How Tos/Calc: Date & Time functions - Apache OpenOffice Wiki)。

デフォルトでは1899年12月30日からの日数になっていて、時間は小数で表現されます。

例えば43033.25がdate-time serial numberとすると小数点以下の00.25は24x0.25=6、つまり午前6時を意味して、2017年10月25日午前6時になります。

セルに日付書式を設定する方法


date-time serial numberは計算には便利ですが、そのまま表示しても意味がわからないので、B2からB4セルでは書式設定をしてわかりやすい表示にしています。

セルの書式設定の方法はLibreOffice5(84)Javaの例:GUIをPythonにする その9でやったUnoControlFormattedFieldと同じようにしてできました。
  numberformats = doc.getNumberFormats()  # ドキュメントのフォーマット一覧を取得。デフォルトのフォーマット一覧はCalcの書式→セル→数値でみれる。
  locale = Locale(Language="ja", Country="JP")  # フォーマット一覧をくくる言語と国を設定。インストールしていないUIの言語でもよい。。 
  formatkey = numberformats.queryKey(formatstring, locale, True)  # formatstringが既存のフォーマット一覧にあるか調べて取得。第3引数のブーリアンは意味はないはず。 
  if formatkey == -1:  # デフォルトのフォーマットにformatstringがないとき。
   formatkey = numberformats.addNew(formatstring, locale)  # フォーマット一覧に追加する。保存はドキュメントごと。 
ダイアログのときと違ってNumberFormatsSupplierはドキュメントモデルからgetNumberFormats()メソッドで取得できます。

formatstringは数の書式コード - LibreOffice Helpを使って表現します。

数の書式コードはドキュメントごとに保存されていて、デフォルトの数の書式コードは、書式→セル→数値、で確認できます。

デフォルトにない書式コードは「ユーザー定義」カテゴリーにaddNew()メソッドで登録します。

書式コードは言語ごとに異なるので31行目で言語を指定しています。

YYYY-MM-DD はja_JPでもen_US(Locale(Language="en", Country="US"))でも有効です。

しかしde_DE(Locale(Language="de", Country="DE"))では、その結果はYYYY-10-DDとなってしまって年と日が正しく表示されません。

de_DEはドイツ語でZahlenformat-Codes - LibreOffice Helpをみると年はJ、日はTで表現します。

そのためドイツ語では書式コードはJJJJ-MM-TTとしないといけません。

書式コードはユーザーインターフェイスのインストール言語とはまた別もののようで、ユーザーインターフェイスでは日本語と英語(米国)しかインストールしていなくてもde_DEの書式コードが使えました。

なので、その言語固有の書式コードを使うのでなければ常にja_JPにしておいてよいことになります。

書式コードをGE.MM.DDにしたB3セルでは年号で表示されています。

B4セルでは標準書式を設定しています。

標準書式は、書式→セル→数値、日付で選択状態になっている書式コードのことです。

このダイアログでは言語も指定していることになるので、getStandardFormat()メソッドにはプロパティを設定していないLocale Structを渡しています。

NumberFormatsのサービスとインターフェイス一覧

def macro():
 ctx = XSCRIPTCONTEXT.getComponentContext()  # コンポーネントコンテクストの取得。
 smgr = ctx.getServiceManager()  # サービスマネージャーの取得。 
 tcu = smgr.createInstanceWithContext("pq.Tcu", ctx)  # サービス名か実装名でインスタンス化。
 doc = XSCRIPTCONTEXT.getDocument()  # Calcドキュメント。
 numberformats = doc.getNumberFormats()
 tcu.wtree(numberformats)
LibreOffice5(86)拡張機能: TCU - Tree Command for UNO の作成のTCUで取得した結果です。

└─.util.NumberFormats
     ├─.util.XNumberFormatTypes
     │         long  getFormatForLocale( [in]         long nKey,
     │                                   [in] .lang.Locale nLocale)
     │         long  getFormatIndex( [in]        short nIndex,
     │                               [in] .lang.Locale nLocale)
     │         long  getStandardFormat( [in]        short nType,
     │                                  [in] .lang.Locale nLocale)
     │         long  getStandardIndex( [in] .lang.Locale nLocale)
     │      boolean  isTypeCompatible( [in] short nOldType,
     │                                 [in] short nNewType)
     └─.util.XNumberFormats
                          long  addNew( [in]       string aFormat,
                                        [in] .lang.Locale nLocale
                             ) raises ( .util.MalformedNumberFormatException)
                          long  addNewConverted( [in]       string aFormat,
                                                 [in] .lang.Locale nLocale,
                                                 [in] .lang.Locale nNewLocale
                                      ) raises ( .util.MalformedNumberFormatException)
                        string  generateFormat( [in]         long nBaseKey,
                                                [in] .lang.Locale nLocale,
                                                [in]      boolean bThousands,
                                                [in]      boolean bRed,
                                                [in]        short nDecimals,
                                                [in]        short nLeading)
           .beans.XPropertySet  getByKey( [in] long nKey)
                          long  queryKey( [in]       string aFormat,
                                          [in] .lang.Locale nLocale,
                                          [in]      boolean bScan)
                        [long]  queryKeys( [in]        short nType,
                                           [in] .lang.Locale nLocale,
                                           [in]      boolean bCreate)
                          void  removeByKey( [in] long nKey)

参考にしたサイト


日付と時刻関数 - LibreOffice Help,
日付と時刻は合わせてシリアル値でセルに保持されています。

Documentation/How Tos/Calc: Date & Time functions - Apache OpenOffice Wiki
Calcの日時に関するヘルプ。

数の書式コード - LibreOffice Help
Calcの書式コードは言語によって異なるので、異なる言語の情報はこのヘルプをその言語に切替えると表示されます。

次の関連記事:Calc(32)sheet["A1"]とsheet[0, 0]とsheet[0:1, 0]の違い

ブログ検索 by Blogger

Translate

最近のコメント

Created by Calendar Gadget

QooQ