前回の記事では、Power Apps上でActiveReportsを利用する為、ActiveReportsのJSビューワをPower Appsのコードコンポーネントとして実装する方法と、ビューワに帳票機能を提供するASP.NET Core Webアプリの実装について解説いたしました。
今回の記事では、作成したコードコンポーネントをキャンバスアプリ上に配置して、実際にPower Apps上で帳票を開発する方法についてもご紹介していきます。
事前準備
今回は前回使用した開発環境に加え、新たに次の環境を用意します。
- Build Tools for Visual Studio 2022(パッケージ化する為のビルドツール)
- Power Apps 開発者向けプラン(Power Apps環境)
前回までに使用した環境は以下の通りです。
- Visual Studio Code
- Npm or Node.JS ※ LTS (長期サポート) バージョンのご利用をお勧め
- Power Platform CLI(Power Apps Component Frameworkを利用する為のツール)
- OS:Windows 11(23H2)
- IDE:Visual Studio 2022(Version 17.9.5)
- ActiveReports:18.0J (v18.0.0.0)
製品版の最新バージョンは以下より入手可能です。
トライアル版は無料で以下より入手可能です。
ActiveReportsビューワコンポーネントをPower Apps環境で利用する
ビューワコンポーネントのパッケージ化
それでは、前回までに作成した「コードコンポーネント」をPower Apps環境へアップする為にコンポーネントをパッケージ化していきます。
コードコンポネントのパッケージ化に詳細は以下で詳しく解説しています。
パッケージ化を行うためには、ソリューションプロジェクトを作成する必要があります。そのため、まずプロジェクトフォルダを作成する必要があります。また、ソリューションプロジェクトの作成時に「publisher-name」と「publisher-prefix」の指定が必要となります。今回は以下のように設定します。
- フォルダ名:ARdotNetViewerSolution(ARdotNetViewerPCFの配下に作成します)
- publisher-name(ソリューション発行者):ardotnet
- publisher-prefix(ソリューション発行者を表すカスタマイズの接頭辞の値):ard
「コンポーネントのパッケージ化を行う方法」にしたがって、ビルドを行うと、次のようにコードコンポーネントがパッケージ化され「ARdotNetViewerSolution.zip」が作成されます。
Power Apps環境の設定
続いて、作成したパッケージをPower Apps環境で利用できるように以下の設定を行います。
- コードコンポーネントの利用設定
- コンポーネントのアップロードサイズ設定
詳しい環境設定の方法については、次の記事をご覧ください。
コンポーネントの利用するためのPower Apps環境の設定
https://devlog.mescius.jp/powerapps-component-framework-2/#Components-EnvironmentSetting
Power Apps 環境へアップロード
環境設定終了後、Power Apps 画面を開き、サイドバー「ソリューション」から次の動画のように作成したコンポーネントパッケージをアップロード(ソリューションをインポート)します。
パッケージのアップロードが完了すると、以下の図のようにパッケージが「ソリューション」としてアップロードされます。
Power Appsキャンバスアプリ上に帳票を作成
ここまでで、作成したコンポーネントを利用する準備が整いましたので、続いてはキャンバスアプリ上で、コンポーネントの利用した帳票機能を作成していきます。
キャンバスアプリ上にコードコンポーネントを追加
それでは、さっそく空のキャンバスアプリを作成していきます。初期状態では、コンポーネントの「挿入」メニューには追加したコンポーネントは表示されていませんので、以下のように追加してきます。
キャンバスアプリを作成
メニュー上からコンポーネントの追加も可能となりましたので、実際にキャンバスアプリを作成していきます。
まず、以下の図の青枠内のようにコンポーネントを配置し、アプリケーションのデザインを行います。
続いて追加したコンポーネントに、以下のプロパティを設定していきます。
「垂直コンテナ」コンポーネントのプロパティ設定
プロパティ | 設定値 |
---|---|
コンポーネント名 | Container1 |
Height | Parent.Height |
Width | Parent.Width |
X | 0 |
Y | 0 |
「コンテナ」コンポーネントのプロパティ設定
プロパティ | 設定値 |
---|---|
コンポーネント名 | Container2 |
Fill | RGBA(12, 161, 117, 1) |
Height | 110 |
Width | Parent.Width |
X | 0 |
Y | 0 |
「ラベル」コンポーネントのプロパティ設定
プロパティ | 設定値 |
---|---|
コンポーネント名 | Label1 |
Height | Parent.Height |
Width | 1000 |
X | 0 |
Y | 0 |
Text | “ActiveReports for .NET on Power Apps” |
※ プロパティペインから入力する際は「”」は不要です。 | |
FontWeight | Semibold |
Size | 36 |
Color | RGBA(255, 255, 255, 1) |
PaddingLeft | 50 |
「切替」コンポーネントのプロパティ設定
プロパティ | 設定値 |
---|---|
コンポーネント名 | Toggle1 |
Height | 56 |
Width | 160 |
X | 1150 |
Y | 27 |
「水平コンテナ」コンポーネントのプロパティ設定
プロパティ | 設定値 |
---|---|
コンポーネント名 | Container3 |
Height | Parent.Height-110 |
Width | Parent.Width |
X | 0 |
Y | 0 |
LayoutMinHeight | Parent.Height-110 |
「ギャラリー」配下のコンポーネントのプロパティ設定
コンポーネント | プロパティ | 設定値 |
---|---|---|
ギャラリー | コンポーネント名 | Gallery1 |
Items | [ {reportsid:”AcmeStore.rdlx”}, {reportsid:”AnnualReport.rdlx”}, {reportsid:”Invoice.rdlx”}, {reportsid:”Invoice.rpx”}, {reportsid:”Invoice_Colored.rpx”}, {reportsid:”InvoiceList.rdlx”}, {reportsid:”Project & Resource Analysis – Staff Performance Analysis.rdlx”}, {reportsid:”Statistical analysis scatter plot.rdlx”}, {reportsid:”User defined report columns.rdlx”} ] | |
Height | Parent.Height-110 | |
Width | Parent.Width | |
X | 0 | |
Y | 0 | |
LayoutMinHeight | 200 | |
レイアウト | タイトル | |
四角形 ※デフォルト設定のまま | コンポーネント名 | Rectangle1 |
四角形 ※デフォルト設定のまま | コンポーネント名 | Separator1 |
アイコン ※デフォルト設定のまま | コンポーネント名 | NextArrow1 |
ラベル | コンポーネント名 | Title1 |
Text | ThisItem.reportsid |
「ActiveReportsビューワコードコンポネント」のプロパティ設定
プロパティ | 設定値 |
---|---|
コンポーネント名 | ARdotNetViewer1 |
FillPortions | 1 |
Height | Parent.Height |
Width | Parent.Width-Gallery1.Width |
X | 0 |
Y | 0 |
LayoutMinHeight | 1000 |
「ActiveReportsビューワコードコンポネント」には、上記の設定に加えて、独自に実装したプロパティ設定の追加も行います。
プロパティ | 設定値 |
---|---|
Server_Url | 「AcitveReports ASP.NET Core Webアプリ」のホスト名を指定します。 今回は、前回Azure上にデプロイしたWebアプリのホストを指定します。 「https://任意のアプリケーション名.azurewebsites.net/”」 |
Reports_ID | 表示するレポートを指定します。 今回は次のように、ギャラリー上列挙されたレポートを、選択した内容が表示できるように以下に用に設定します。 「Gallery1.Selected.reportsid」 |
Reports_Loading | レポートの読み込みを行うかどうかの設定です。 レポート設定が行われていない場合に読込を行うとエラーとなる動作の抑制を行います。 今回はアプリケーション上から、制御できるように切替コンポネントにて操作可能なように以下を設定します。 「Toggle1.Value」 |
Style_Width | ビューワコンポーネントのスタイル設定(幅)です。 今回は、他のコンポーネントのサイズに連動して動作するよう以下を設定しています。 (Parent.Width-Gallery1.Width) &”px” |
Style_Height | ビューワコンポーネントのスタイル設定(高さ)です。 今回は、他のコンポーネントのサイズに連動して動作するよう以下を設定しています。 Parent.Height & “px” |
ここまで実施した、レイアウト作成とプロパティ設定により、帳票アプリの作成が完了となります。動作を確認すると、次の動画のように帳票アプリの基本的な動作である、「印刷プレビュー」、「印刷」、「PDFエクスポート」などが可能なことがわかります。また、「Power Apps」のギャラリーコンポーネント上から、出力する帳票を選択することで、複数の帳票を簡単に表示することも可能です。
Power Appsからのデータを帳票に利用
ここまでご紹介した内容では、あらかじめデータの設定までが行われた帳票を表示してきましたが、ここからは、Power Apps上に用意されたデータを利用した帳票を作成してみます。
レポートパラメータをデータソースとする帳票レイアウトの作成
新たな帳票レイアウトとして、以下のようなレイアウトをActiveReportsの帳票デザイナを利用し作成します。
この帳票レイアウトには、以下のように帳票出力の際にパラメータを渡すための「レポートパラメータ」を追加しています。
また、この「レポートパラメータ」を帳票のデータソースとして利用するため、データソースには以下のように追加済みの「ReportParameter1」を参照するように設定を行っています。
帳票レイアウトの作成は以上となります。細かなレポートの内容については、こちらをダウンロードの上ご確認ください。
ASP.NET Core Webアプリにレポートを追加し再デプロイ
作成した帳票レイアウトを、ASP.NET Core Webアプリに追加し、再度Azure上へデプロイします。
Azureへのデプロイについては以下をご覧ください。
ActiveReportsビューワコンポーネントにレポートパラメータプロパティを追加
帳票レイアウト、バックエンドWebアプリに続いて、作成済みのコードコンポーネントにレポートパラメータを渡すためのプロパティを追加します。今回変更する必要があるソースコードは以下となります。
マニフェストファイルの更新
<?xml version="1.0" encoding="utf-8" ?>
<manifest>
<control namespace="ARdotNet" constructor="ARdotNetViewer" version="0.0.1" display-name-key="ARdotNetViewer" description-key="ARdotNetViewer description" control-type="virtual" >
<!--external-service-usageノードは、このサードパーティPCFコントロールが外部サービスを使用しているかどうかを宣言します。もし使用している場合、このコントロールはプレミアムと見なされ、使用している外部ドメインも追加してください。
外部サービスを使用していない場合、enabled="false"に設定し、以下にドメインを追加しないでください。"enabled"はデフォルトでfalseになります。
例1:
<external-service-usage enabled="true">
<domain>www.Microsoft.com</domain>
</external-service-usage>
例2:
<external-service-usage enabled="false">
</external-service-usage>
-->
<external-service-usage enabled="true">
<domain>http://example.com/</domain>
<!--外部ドメインを追加するにはコメントを解除してください
<domain></domain>
<domain></domain>
-->
</external-service-usage>
<!-- propertyノードは、コントロールがCDSから期待する特定の設定可能なデータを識別します -->
<!-- <property name="sampleProperty" display-name-key="Property_Display_Key" description-key="Property_Desc_Key" of-type="SingleLine.Text" usage="bound" required="true" /> -->
<property name="Server_Url" display-name-key="Server_Url" description-key="ActiveReport.Netのバックエンドサーバーを指定します。" of-type="SingleLine.Text" pfx-default-value ='"http://example.com/"' usage="input" required="true" />
<property name="Reports_ID" display-name-key="Reports_ID" description-key="表示するレポートを指定します。" of-type="SingleLine.Text" pfx-default-value ='"Invoice.rdlx"' usage="input" required="true"/>
<property name="Reports_Loading" display-name-key="Reports_Loading" description-key="レポートの読み込みを行うかを指定します。" of-type="TwoOptions" pfx-default-value ='false' usage="input" required="true"/>
<property name="Reports_Parameter" display-name-key="Reports_Parameter" description-key="レポートへパラメータを渡します。" of-type="Multiple" usage="input" required="false"/>
<property name="Style_Width" display-name-key="Style_Width" description-key="ビューワの横幅を指定します。" of-type="SingleLine.Text" pfx-default-value ='"100%"' usage="input" required="true"/>
<property name="Style_Height" display-name-key="Style_Height" description-key="ビューワの高さを指定します。" of-type="SingleLine.Text" pfx-default-value ='"100vh"' usage="input" required="true"/>
<!--
プロパティノードの of-type 属性は of-type-group 属性にすることができます。
例:
<type-group name="numbers">
<type>Whole.None</type>
<type>Currency</type>
<type>FP</type>
<type>Decimal</type>
</type-group>
<property name="sampleProperty" display-name-key="Property_Display_Key" description-key="Property_Desc_Key" of-type-group="numbers" usage="bound" required="true" />
-->
<resources>
<code path="index.ts" order="1"/>
<platform-library name="React" version="16.8.6" />
<!-- <platform-library name="Fluent" version="8.29.0" /> -->
<css path="css/App.css" order="1" />
<css path="css/jsViewer.min.css" order="2" />
<css path="css/jsViewer.chart.min.css" order="3" />
<!-- 追加のリソースを追加するにはコメントを解除してください
<css path="css/ARdotNetViewer.css" order="1" />
<resx path="strings/ARdotNetViewer.1033.resx" version="1.0.0" />
-->
</resources>
<!-- 指定されたAPIを有効にするにはコメントを解除してください
<feature-usage>
<uses-feature name="Device.captureAudio" required="true" />
<uses-feature name="Device.captureImage" required="true" />
<uses-feature name="Device.captureVideo" required="true" />
<uses-feature name="Device.getBarcodeValue" required="true" />
<uses-feature name="Device.getCurrentPosition" required="true" />
<uses-feature name="Device.pickFile" required="true" />
<uses-feature name="Utility" required="true" />
<uses-feature name="WebAPI" required="true" />
</feature-usage>
-->
</control>
</manifest>
tsxファイルの更新
import * as React from 'react';
// 型定義
interface GrapeCity {
ActiveReports: {
JSViewer: {
create: (config: { element: string; reportService: { url: string } }) => ViewerInstance;
};
};
}
// ViewerInstance の型定義
interface ViewerInstance {
openReport: (
report: string | null,
reportParameters: Array<{ name: string; values: string[]}>
) => void;
}
interface Window {
GrapeCity: GrapeCity;
}
declare let window: Window;
// 追加するプロパティ
export interface IViewerProps {
Server_Url?: string | null;
Reports_ID?: string | null;
Reports_Loading?: boolean | false;
Reports_Parameter?: string | null;
Style_Width?: string;
Style_Height?: string;
}
export class Viewer extends React.Component<IViewerProps> {
viewer: ViewerInstance | null = null;
constructor(props: IViewerProps) {
super(props);
}
componentDidMount() {
let _reportParameters: Array<{ name: string; values: string[] }> = [];
if (window.GrapeCity && window.GrapeCity.ActiveReports) {
if (this.props.Reports_Parameter) {
try {
_reportParameters = [JSON.parse(this.props.Reports_Parameter)];
} catch (error) {
console.error("Failed to parse Reports_Parameter:", error);
}
}
this.viewer = window.GrapeCity.ActiveReports.JSViewer.create({
element: '#viewer-host',
reportService: {
url: (this.props.Server_Url ?? '') + 'api/reporting',
},
});
if (this.props.Reports_Loading) {
this.viewer.openReport(this.props.Reports_ID ?? null, _reportParameters );
}
}
}
componentDidUpdate() {
let _reportParameters: Array<{ name: string; values: string[] }> = [];
if (this.props.Reports_Parameter) {
try {
_reportParameters = [JSON.parse(this.props.Reports_Parameter)];
} catch (error) {
console.error("Failed to parse Reports_Parameter:", error);
}
}
if (this.viewer && this.props.Reports_Loading) {
this.viewer.openReport(this.props.Reports_ID ?? null, _reportParameters);
}
}
render() {
const viewerStyle = {
width: this.props.Style_Width || '100%',
height: this.props.Style_Height || '100vh'
};
return (
<div>
<div id="viewer-host" style={viewerStyle} />
</div>
);
}
}
index.tsファイルの更新
import { IInputs, IOutputs } from "./generated/ManifestTypes";
import { Viewer, IViewerProps } from "./App";
import * as React from "react";
import "@mescius/activereportsnet-viewer-ja/dist/jsViewer.min.js";
export class ARdotNetViewer implements ComponentFramework.ReactControl<IInputs, IOutputs> {
private theComponent: ComponentFramework.ReactControl<IInputs, IOutputs>;
private notifyOutputChanged: () => void;
private props: IViewerProps = { Server_Url: 'http://example.com/', Reports_ID: 'Invoice.rdlx', Reports_Loading:false, Reports_Parameter:null, Style_Width: '100%', Style_Height: '100vh' };
/**
* 空のコンストラクタ。
*/
constructor() { }
/**
* コントロールのインスタンスを初期化するために使用されます。ここでリモートサーバー呼び出しや他の初期化アクションを開始できます。
* データセットの値はここでは初期化されません。updateViewを使用してください。
* @param context コンテキストオブジェクトを介して制御できるプロパティバッグ全体。これは、マニフェストで定義されたプロパティ名にマッピングされたカスタマイザによって設定された値やユーティリティ関数を含みます。
* @param notifyOutputChanged コントロールに新しい出力が非同期で取得可能であることをフレームワークに通知するコールバックメソッド。
* @param state 単一ユーザーの1つのセッション内で持続するデータ。Modeインターフェイスで 'setControlState' を呼び出すことにより、コントロールのライフサイクルの任意の時点で設定できます。
*/
public init(
context: ComponentFramework.Context<IInputs>,
notifyOutputChanged: () => void,
state: ComponentFramework.Dictionary
): void {
this.notifyOutputChanged = notifyOutputChanged;
this.props.Server_Url = context.parameters.Server_Url.raw || 'http://example.com/';
this.props.Reports_ID = context.parameters.Reports_ID.raw || 'Invoice.rdlx';
this.props.Reports_Loading = context.parameters.Reports_Loading.raw.valueOf() || false;
this.props.Reports_Parameter = context.parameters.Reports_Parameter.raw || null;
this.props.Style_Width = context.parameters.Style_Width?.raw || '100%';
this.props.Style_Height = context.parameters.Style_Height?.raw || '100vh';
}
/**
* プロパティバッグ内の任意の値が変更されたときに呼び出されます。これには、フィールド値、データセット、コンテナの高さや幅などのグローバル値、オフラインステータス、ラベル、可視性などのコントロールメタデータ値が含まれます。
* @param context コンテキストオブジェクトを介して制御できるプロパティバッグ全体。これは、マニフェストで定義された名前にマッピングされたカスタマイザによって設定された値やユーティリティ関数を含みます。
* @returns ReactElement コントロールのルートReact要素を返します。
*/
public updateView(context: ComponentFramework.Context<IInputs>): React.ReactElement {
this.props.Server_Url = context.parameters.Server_Url.raw || 'http://example.com/';
this.props.Reports_ID = context.parameters.Reports_ID.raw || 'Invoice.rdlx';
this.props.Reports_Loading = context.parameters.Reports_Loading.raw.valueOf() || false;
this.props.Reports_Parameter = context.parameters.Reports_Parameter.raw || null;
this.props.Style_Width = context.parameters.Style_Width?.raw || '100%';
this.props.Style_Height = context.parameters.Style_Height?.raw || '100vh';
return React.createElement(
Viewer, this.props
);
}
/**
* コントロールが新しいデータを受け取る前に、フレームワークによって呼び出されます。
* @returns マニフェストで定義された命名法に基づくオブジェクトを返します。「bound」または「output」とマークされたプロパティに対するオブジェクトを期待します。
*/
public getOutputs(): IOutputs {
return { };
}
/**
* コントロールがDOMツリーから削除されるときに呼び出されます。コントロールはこの呼び出しを使用してクリーンアップを行うべきです。
* 例: 保留中のリモート呼び出しのキャンセル、リスナーの削除など。
*/
public destroy(): void {
// 必要に応じてコントロールをクリーンアップするコードを追加
}
}
ソースコードの修正が終わったら、ビルド後、パッケージ化しPower Apps環境へアップロードしてください。
※ コードコンポーネントが同一の場合、コードコンポーネントのバージョンを上げてもキャンバスアプリに追加できないことがあります。その場合は、別名のコードコンポーネントを作成のうえ再度アップロードしてご利用ください。
キャンバスアプリ上に画面を追加
Power Appsからのデータを帳票に利用する準備が整いましたので、作成中のキャンバスアプリの画面を追加して、Power Appsからのデータを渡した帳票アプリを作成します。
この画面では次のような機能を実装することで、Power Appsのデータをビューワコンポーネントを介し、サーバーへ渡し、サーバーで作成された帳票をビューワへ表示します。
- 画面表示時にデータを読みこむ
- データを、表形式に配置したテキスト入力コンポーネントへ設定
- 印刷アイコンを押し、テキスト入力の値をコンテキスト変数「setValue」へレポートパラメータへ渡せる形式として保存
- テキスト入力「Screen2JSonTextInput」の初期値を「setValue」とする
- 「ActiveReportsビューワコードコンポネント」の「Reports_Parameter」プロパティの設定値を「Screen2JSonTextInput.Text」として、パラメータ値を設定
- Screen2Toggle1.Valueの状態によって、ビューワのロードが始まる
ビューワ上に帳票表示後、印刷やPDFが可能となります。
それでは、実際に以下のように画面レイアウトを構成しアプリケーションを作成していきます。
まず画面「Screen2」を追加します。画面の表示時に請求書のデータが利用できるように、OnVisibleプロパティに「invoice」というJSON形式の埋込データを設定します。
OnVisibleプロパティの設定
プロパティ | 設定値 |
---|---|
OnVisible | ClearCollect(invoice,{companyname:”テスト企業1”,no:”DB-00001″,sku:”7948352″,name:”モッツァレッラチーズとトマトのサラダ”,unit:”120″,price:”1200″,remark:”前菜”},{companyname:”テスト企業1”,no:”DB-00001″,sku:”1797382″,name:”ナポリ風スパゲティー”,unit:”60″,price:”2500″,remark:”パスタ”},{companyname:”テスト企業1”,no:”DB-00001″,sku:”9963274″,name:”小羊背肉のリンゴソースかけ”,unit:”130″,price:”5000″,remark:”メイン”},{companyname:”テスト企業2”,no:”DB-00002″,sku:”8398400″,name:”超極厚牛タン”,unit:”130″,price:”4800″,remark:”肉”},{companyname:”テスト企業2”,no:”DB-00002″,sku:”7079356″,name:”濃厚ずんだロール”,unit:”20″,price:”780″,remark:”デザート”},{companyname:”テスト企業2”,no:”DB-00002″,sku:”6407829″,name:”ハチミツパンケーキ”,unit:”120″,price:”1300″,remark:”お持ち帰り”},{companyname:”テスト企業3”,no:”DB-00003″,sku:”7627259″,name:”マスクメロン”,unit:”90″,price:”1100″,remark:”フルーツ”},{companyname:”テスト企業3”,no:”DB-00003″,sku:”8238079″,name:”ラ・フランス”,unit:”150″,price:”700″,remark:”フルーツ”}); |
その他の項目のプロパティ設定は以下を参考に設定してください。
「ラベル:Screen2Titlelabel」コンポーネントのプロパティ設定
プロパティ | 設定値 |
---|---|
コンポーネント名 | Screen2Titlelabel |
Height | 82 |
Width | 1027 |
X | 0 |
Y | 0 |
Color | RGBA(255, 255, 255, 1) |
PaddingLeft | 50 |
FontWeight | Semibold |
Size | 36 |
Text | “Power Apps data for Reports DataSource” |
「切替:Screen2Toggle1」コンポーネントのプロパティ設定
プロパティ | 設定値 |
---|---|
コンポーネント名 | Screen2Toggle1 |
Height | 56 |
Width | 160 |
X | 1083 |
Y | 17 |
「四角形:Screen2TitleRectangle1」コンポーネントのプロパティ設定
プロパティ | 設定値 |
---|---|
コンポーネント名 | Screen2TitleRectangle1 |
Height | 82 |
Width | Parent.Width |
X | 0 |
Y | 0 |
Fill | RGBA(100, 118, 132, 1) |
「アイコン:Screen2PrintIcon」コンポーネントのプロパティ設定
プロパティ | 設定値 |
---|---|
コンポーネント名 | Screen2PrintIcon |
Height | 64 |
Width | 64 |
X | 1275 |
Y | 9 |
アイコン | Icon.Print |
OnSelect | UpdateContext({setvalue:””});UpdateContext({setvalue: “{” & “””” & “name” & “””” & “:” & “””” & “ReportParameter1” & “””” & “,” & “””” & “values” & “””” & “:[” & “””” & “[” & “{” & “¥” & “””” & “companyname” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec1_Col1.Text & “¥” & “””” & “,” & “¥” &”””” & “no” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec1_Col2.Text & “¥” & “””” & “,” & “¥” &”””” & “sku” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec1_Col3.Text & “¥” & “””” & “,” & “¥” &”””” & “name” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec1_Col4.Text & “¥” & “””” & “,” & “¥” & “””” & “unit” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec1_Col5.Text & “¥” & “””” & “,” & “¥” & “””” & “price” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec1_Col6.Text & “¥” & “””” & “,” & “¥” & “””” & “remark” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec1_Col7.Text & “¥” & “””” & “}” & “,{” & “¥” & “””” & “companyname” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec2_Col1.Text & “¥” & “””” & “,” & “¥” &”””” & “no” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec2_Col2.Text & “¥” & “””” & “,” & “¥” &”””” & “sku” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec2_Col3.Text & “¥” & “””” & “,” & “¥” &”””” & “name” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec2_Col4.Text & “¥” & “””” & “,” & “¥” & “””” & “unit” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec2_Col5.Text & “¥” & “””” & “,” & “¥” & “””” & “price” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec2_Col6.Text & “¥” & “””” & “,” & “¥” & “””” & “remark” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec2_Col7.Text & “¥” & “””” & “}” & “,{” & “¥” & “””” & “companyname” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec3_Col1.Text & “¥” & “””” & “,” & “¥” &”””” & “no” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec3_Col2.Text & “¥” & “””” & “,” & “¥” &”””” & “sku” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec3_Col3.Text & “¥” & “””” & “,” & “¥” &”””” & “name” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec3_Col4.Text & “¥” & “””” & “,” & “¥” & “””” & “unit” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec3_Col5.Text & “¥” & “””” & “,” & “¥” & “””” & “price” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec3_Col6.Text & “¥” & “””” & “,” & “¥” & “””” & “remark” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec3_Col7.Text & “¥” & “””” & “}” & “,{” & “¥” & “””” & “companyname” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec4_Col1.Text & “¥” & “””” & “,” & “¥” &”””” & “no” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec4_Col2.Text & “¥” & “””” & “,” & “¥” &”””” & “sku” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec4_Col3.Text & “¥” & “””” & “,” & “¥” &”””” & “name” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec4_Col4.Text & “¥” & “””” & “,” & “¥” & “””” & “unit” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec4_Col5.Text & “¥” & “””” & “,” & “¥” & “””” & “price” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec4_Col6.Text & “¥” & “””” & “,” & “¥” & “””” & “remark” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec4_Col7.Text & “¥” & “””” & “}” & “,{” & “¥” & “””” & “companyname” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec5_Col1.Text & “¥” & “””” & “,” & “¥” &”””” & “no” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec5_Col2.Text & “¥” & “””” & “,” & “¥” &”””” & “sku” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec5_Col3.Text & “¥” & “””” & “,” & “¥” &”””” & “name” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec5_Col4.Text & “¥” & “””” & “,” & “¥” & “””” & “unit” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec5_Col5.Text & “¥” & “””” & “,” & “¥” & “””” & “price” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec5_Col6.Text & “¥” & “””” & “,” & “¥” & “””” & “remark” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec5_Col7.Text & “¥” & “””” & “}” & “,{” & “¥” & “””” & “companyname” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec6_Col1.Text & “¥” & “””” & “,” & “¥” &”””” & “no” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec6_Col2.Text & “¥” & “””” & “,” & “¥” &”””” & “sku” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec6_Col3.Text & “¥” & “””” & “,” & “¥” &”””” & “name” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec6_Col4.Text & “¥” & “””” & “,” & “¥” & “””” & “unit” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec6_Col5.Text & “¥” & “””” & “,” & “¥” & “””” & “price” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec6_Col6.Text & “¥” & “””” & “,” & “¥” & “””” & “remark” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec6_Col7.Text & “¥” & “””” & “}” & “,{” & “¥” & “””” & “companyname” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec7_Col1.Text & “¥” & “””” & “,” & “¥” &”””” & “no” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec7_Col2.Text & “¥” & “””” & “,” & “¥” &”””” & “sku” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec7_Col3.Text & “¥” & “””” & “,” & “¥” &”””” & “name” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec7_Col4.Text & “¥” & “””” & “,” & “¥” & “””” & “unit” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec7_Col5.Text & “¥” & “””” & “,” & “¥” & “””” & “price” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec7_Col6.Text & “¥” & “””” & “,” & “¥” & “””” & “remark” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec7_Col6.Text & “¥” & “””” & “}” & “,{” & “¥” & “””” & “companyname” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec8_Col7.Text & “¥” & “””” & “,” & “¥” &”””” & “no” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec8_Col6.Text & “¥” & “””” & “,” & “¥” &”””” & “sku” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec8_Col5.Text & “¥” & “””” & “,” & “¥” &”””” & “name” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec8_Col4.Text & “¥” & “””” & “,” & “¥” & “””” & “unit” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec8_Col3.Text & “¥” & “””” & “,” & “¥” & “””” & “price” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec8_Col2.Text & “¥” & “””” & “,” & “¥” & “””” & “remark” & “¥” & “””” & “:” & “¥” & “””” & Screen2TableRec8_Col1.Text & “¥” & “””” & “}”&”]” & “””” & “]” &”}” }); |
「テキスト入力:Screen2JSonTextInput」コンポーネントのプロパティ設定
プロパティ | 設定値 |
---|---|
コンポーネント名 | Screen2JSonTextInput |
Height | 244 |
Width | 587 |
X | 14 |
Y | 500 |
Default | setvalue |
「表形式のラベル、テキスト入力」コンポーネントのプロパティ設定
コンポーネント | プロパティ | 設定値 |
---|---|---|
ラベル | コンポーネント名 | Screen2TableLabelCol(1~7) |
Height | 40 | |
Width | Col1:137,Col2:67,Col3:61,Col4:140,Col5:37,Col6:50,Col7:96 | |
X | Col1:14,Col2:151,Col3:218,Col4:279,Col5:419,Col6:455,Col7:505 | |
Y | 106 | |
Fill | RGBA(100, 118, 132, 1) | |
Text | Col1:”会社名”,Col2:”伝票番号”,Col3:”商品番号”,Col4:”商品名”,Col5:”数量”,Col6:”単価”,Col7:”備考” | |
Size | 9 | |
Color | RGBA(255, 255, 255, 1) | |
Align | Center | |
VerticalAlign | Middle | |
BorderThickness | 1 | |
BorderColor | RGBA(32, 54, 71, 1) | |
テキスト入力 | コンポーネント名 | Screen2TableRec(1~8)_Col(1~7) |
Height | 43 | |
Width | Screen2TableLabelCol(1~7).Width | |
X | Screen2TableLabelCol(1~7).X | |
Y | Rec1_Col(1~7):145,Rec2_Col(1~7):188,Rec3_Col(1~7):231,Rec4_Col(1~7):274,Rec5_Col(1~7):317,Rec6_Col(1~7):360,Rec7_Col(1~7):403,Rec8_Col(1~7):445 | |
Default | Rec(1~8)_Col1:Index(invoice,1~8).companyname Rec(1~8)_Col2:Index(invoice,1~8).no Rec(1~8)_Col3:Index(invoice,1~8).sku Rec(1~8)_Col4:Index(invoice,1~8).name Rec(1~8)_Col5:Index(invoice,1~8).unit Rec(1~8)_Col6:Index(invoice,1~8).price Rec(1~8)_Col7:Index(invoice,1~8).remark | |
Size | 9 | |
Color | RGBA(255, 255, 255, 1) | |
Align | Rec(1~8)_Col1:Left,Rec(1~8)_Col2:Left,Rec(1~8)_Col3:Right,Rec(1~8)_Col4:Left,Rec(1~8)_Col5:Right,Rec(1~8)_Col6:Right,Rec(1~8)_Col7:Left | |
BorderThickness | 1 | |
BorderColor | RGBA(32, 54, 71, 1) |
画面上のコンポーネント配置、プロパティ設定が終わりましたら、最後に「ActiveReportsビューワコードコンポネント」の設定も行っていきます。以前の設定とほぼ同じですが、先ほど追加したプロパティ「Reports_Parameter」への設定と、「Reports_ID」にも新たに追加した帳票レイアウトを設定してきます。
プロパティ | 設定値 |
---|---|
コンポーネント名 | ARdotNetParamViewer1 |
Height | 662 |
Width | 733 |
X | 623 |
Y | 82 |
Server_Url | ARdotNetViewer1と同様 |
Reports_ID | invoiceparam.rdlx |
Reports_Loading | Screen2Toggle1.Value |
Reports_Parameter | Screen2JSonTextInput.Text |
Style_Height | 662px |
Style_Width | 733px |
動作確認
最後に動作確認を行います。次の動画のように、Power Apps上のデータが帳票のデータソースとして利用され、テキスト入力コンポーネントで編集した内容も即座に反映されていることが確認できます。
帳票機能機能
画面上で編集されたデータを即時に帳票へ反映
Power Appsでは、Microsoft Lists(SharePointリスト)やExcelデータをはじめ、様々なデータソースを利用することができます。そのため、これらのデータを用いてアプリケーションを作成している方も多いでしょう。こうした方々にとって、Power Apps上のデータを活用して簡単に帳票を作成できることは、大きなメリットとなるのではないでしょうか?
さいごに
今回の記事では、作成したコードコンポーネントをキャンバスアプリ上に配置して、実際にPower Apps上で帳票を開発する方法についてご紹介しました。
ご紹介してきた機能を活用することで、既存の帳票アプリケーションを簡単にローコードプラットフォームに移行することが可能になるほか、Power Appsのデータを活用した、新規の帳票の作成も可能です。
また、ActiveReports for .NETには、Web上で帳票の新規作成や変更などの帳票デザインが行えるJavaScriptコンポーネント「Webデザイナ」を提供しています。JSビューワ同様にコードコンポーネントとして作成することで、以下の動画のようにPower Apps上で、帳票レイアウトの新規作成や、既存のレイアウトの変更することも可能です。
これまでActiveReportsをお使いで、既存の帳票資産を活かしてシステム移行を検討中の方や、Power Apps上に高度な帳票機能を追加したいとお考えの方は、ぜひ今回ご紹介したPower AppsとActiveReports for .NETを組み合わせた帳票アプリケーションの開発方法を参考にしていただけると幸いです。
製品の機能を手軽に体験できるデモアプリケーションも公開しておりますので、こちらもご確認ください。
また、ご導入前の製品に関するご相談、ご導入後の各種サービスに関するご質問など、お気軽にお問合せください。