crossframe » Excel http://crossframe.iiv.jp Windows Dev. Site Tue, 07 Nov 2023 06:31:52 +0000 ja hourly 1 https://wordpress.org/?v=3.8.41 FCell / Excel ../../../201601091162/ ../../../201601091162/#comments Sat, 09 Jan 2016 14:46:40 +0000 ../../../?p=1162 .Net in Excel

http://fcell.io/

ExcelでC#やF#を使うとき、このブログでも紹介したことがありますが、VSTOなどの技術を使います。これにはVisual Studioが必要となりますが、このツールはExelだけで、プログラミングができます。まさにこんなプロダクトが欲しかった、と思っていたものです。

環境: Excel 2016 / Windows 10
インストールは、サイトよりダウンロードした、インストーラ
FCell31_32bit.msi
FCell31_64bit.msi
のどちらかを実行するだけです。

fcell01
(起動時読み込まれているところ・・)

上記サイトにとてもわかりやすいデモムービがあります。これをそのまま実行してみました。
fcell02
ユーザ定義関数を実行しているところですが、プログラムを変更すると(Buildボタン押下)セルに結果が反映されます。(リアクティブになっていること確認)
scaleArr関数は、配列数式になっているので、範囲指定した後CTRL+SHIFT+ENTERで決定する。
fcell03

とても素晴らしいです。
ライセンスが、Enterprise Licenceと、Site Licenceというものがありますが、Enterpriseは$1000とちょっと高めなのが残念です。

マイクロソフトのプロダクトで、Excel, PowerShell, F#が好きな私としては、このあたりもっと意欲的なものが出てきてほしいと思っています。こういったツールが純正品ででてくれるとうれしいのですが・・

]]>
../../../201601091162/feed/ 0
Add-in / Office 2016 ../../../201511011139/ ../../../201511011139/#comments Sun, 01 Nov 2015 12:29:31 +0000 ../../../?p=1139 以前、以下の記事でJavaScriptによるExcelのデータ読み書きのテストをしましたが、VisualStudioを使ったものでした。

「Apps for Office」../../../20131104603/

今回は、共有フォルダからアドインを読み込む方法でテストをしてみました。環境について下記を参照しました。

参考) 「Office 2016で進化したOffice アドイン」http://www.ka-net.org/blog/?p=6213

XMLファイル、JavaScriptプログラムは下記を参考にしました。

参考) https://github.com/OfficeDev/office-js-snippet-explorer

https://github.com/OfficeDev/office-js-snippet-explorer/tree/master/excel-snippets/setValueInRange.js

プグラムは、ボタンを押すとExcelのシートに値を書き込むシンプルなものです。
Office2016_01

sample.xml

<?xml version="1.0" encoding="utf-8"?>
<OfficeApp xmlns="http://schemas.microsoft.com/office/appforoffice/1.1" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:type="TaskPaneApp">
  <Id>6492a0e5-b158-47da-9145-6804c67ed8d9</Id>
  <Version>1.0</Version>
  <ProviderName>Microsoft</ProviderName>
  <DefaultLocale>EN-US</DefaultLocale>
  <DisplayName DefaultValue="excel-js-snippet-explorer"/>
  <Description DefaultValue="Contains snippets for ExcelJS."/>
  <Capabilities>
    <Capability Name="Workbook"/>
  </Capabilities>

  <DefaultSettings>
    <SourceLocation DefaultValue="http://192.168.11.111/sample.html"/>

  </DefaultSettings>
  <Permissions>ReadWriteDocument</Permissions>
</OfficeApp>

Idは、

Wscript.Echo LCase(Mid(CreateObject(“Scriptlet.TypeLib”).GUID, 2, 36))

で生成できます。
このファイルを共有フォルダに置きExcelから選択します。
共有フォルダは、Excelを使用するWindowsに、C:\Shareのように作成して、共有設定します。
ここをExcelオプション->セキュリティセンタ->信頼できるアドインカタログのアドレスに追加します。(「メニューに表示する」をチェック)
Excelを起動して、挿入->マイアドイン->共有フォルダで、アドインが現れクリックします。
すると上の画面が表示されます。シート右側に表示されたWeb画面のボタンを押すと、数値が表示されます。
画面ファイルは、xmlファイルに書かれたアクセス先であるWebサーバをどこかに立て、そこに下記ファイルを置きます。

sample.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.1.4.min.js"></script>
<script src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js"></script>
<script>
Office.initialize = function(reason){}
$(function(){
  $("#btn").click(function(){
    Excel.run(function (ctx) {
      ctx.workbook.worksheets.getItem("Sheet1").getRange("A1:C3").values = 7;
      return ctx.sync();
    }).catch(function (error) {
      console.log(error);
    });
  });
});
</script>
</head>
<body>
<h3>Excel Add-in Test</h3>
<input id="btn" type="button" value="OK">
</bo
</html>

以前もこの件の記事を書いたときに思いましたが、JavaScriptとExcelという組み合わせは、とても可能性を秘めていると感じます。しかしまだ使いにくいと思います。もっと簡単に連携できるしくみが欲しいところです。シート上にWebViewが表示できればベストですが・・

]]>
../../../201511011139/feed/ 0
SPARQL in Excel ../../../20140126687/ ../../../20140126687/#comments Sun, 26 Jan 2014 13:20:02 +0000 http://xfra.me/?p=687 今年はじめての投稿になります。
このBlogは初めてちょうど、一年になります。自分の技術向上の目的もこめて最低でも月一回はそのとき興味のあるプログラムネタを投稿しようと決めていましたが、一年なんとかやりきることができました。また今年もがんばりたいと思います。

本年もよろしくお願いいたします。

昨年からOpenDataに興味を持ち、O’Reilly「セマンティックWebプログラミング」等の書籍を読んで部分的なテストはしていましたが、実際に動くものが手元に欲しくなったので、この本のサンプルを参考にSPARQLというクエリー言語を使って試してみました。
取得したデータをExcelに読み込みたかったので、以前の投稿「Excel Add-Ins in Python, PyXLL」でテストしたPyXLLを使いました。

from pyxll import xl_func
import rdflib
from rdflib.graph import ConjunctiveGraph, Namespace

@xl_func("int n: var[]")
def testFunc1(n):
	ret = []
	FBNS = Namespace("http://rdf.freebase.com/ns/")
	g = ConjunctiveGraph()
	g.parse("C:\data\sample.n3", format="n3")
	res = g.query("""SELECT ?name ?year WHERE{
		?movie fb:film.film.initial_release_date ?year .
		?movie fb:film.film.starring ?actor .
		?actor fb:type.object.name ?name . }
		order by ?year ?name""", initNs={'fb':FBNS})
	for t in res:
		ls = list(t)
		ret.append(ls)

pyxll.xllファイルを空のシートにドラッグ&ドロップします。
name,yearの2列、検索結果数の6行以上の範囲を指定して、関数を呼びます。
引数は必要ないですが、”1″を指定しています。

sparql1
(注:範囲指定して決定するとき、Ctl-Shift-Enterを忘れずに)

PyXllの環境にrdflibを導入する必要があります。pyxll.cfgにpythonpath=.を指定して、pyxll.xllと同じフォルダにrdflibのフォルダをコピーしました。
(インストールしてからかなりたっているため、具体的なインストール手順は割愛しました。スミマセン。logsフォルダに出力されるエラーを参考にして環境を構築するとうまくできると思います。)

以下が使用したデータです。
書籍にあったものを、抜粋して作りました。
sample.n3

@prefix fb: <http://rdf.freebase.com/ns/> .

<http://rdf.freebase.com/ns/en.hollywood_homicide> 
    <http://rdf.freebase.com/ns/film.film.directed_by> 
    <http://rdf.freebase.com/ns/en.ron_shelton> ;
<http://rdf.freebase.com/ns/film.film.starring> 
    <http://rdf.freebase.com/ns/en.harrison_ford> , 
    <http://rdf.freebase.com/ns/en.kurupt> , 
    <http://rdf.freebase.com/ns/en.robert_wagner> ;
<http://rdf.freebase.com/ns/film.film.initial_release_date> "2003" .

<http://rdf.freebase.com/ns/en.k_19_the_widowmaker> 
    <http://rdf.freebase.com/ns/film.film.directed_by> 
    <http://rdf.freebase.com/ns/en.kathryn_bigelow> ;
<http://rdf.freebase.com/ns/film.film.starring> 
    <http://rdf.freebase.com/ns/en.harrison_ford> , 
    <http://rdf.freebase.com/ns/en.joss_ackland> ;
<http://rdf.freebase.com/ns/film.film.initial_release_date> "2002" .

<http://rdf.freebase.com/ns/en.becoming_dick> 
    <http://rdf.freebase.com/ns/film.film.directed_by> 
    <http://rdf.freebase.com/ns/en.bob_saget> ;
<http://rdf.freebase.com/ns/film.film.starring> 
    <http://rdf.freebase.com/ns/en.robert_wagner> , 
    <http://rdf.freebase.com/ns/en.bob_saget> ;
<http://rdf.freebase.com/ns/film.film.initial_release_date> "2000" .

<http://rdf.freebase.com/ns/en.kurt_russell> 
    <http://rdf.freebase.com/ns/type.object.name> "Kurt Russell" .
<http://rdf.freebase.com/ns/en.bob_saget> 
    <http://rdf.freebase.com/ns/type.object.name> "Bob Saget" .
<http://rdf.freebase.com/ns/en.harrison_ford> 
    <http://rdf.freebase.com/ns/type.object.name> "Harrison Ford" .
<http://rdf.freebase.com/ns/en.robert_wagner> 
    <http://rdf.freebase.com/ns/type.object.name> "Robert Wagner" .
<http://rdf.freebase.com/ns/en.kurupt> 
    <http://rdf.freebase.com/ns/type.object.name> "Kurupt" .

OpenDataはいろんなデータフォーマットがあるので、目的のサンプルデータをつくるのにもう少し調査が必要と感じました。
まずは第一歩としてここまでにしたいと思います。

]]>
../../../20140126687/feed/ 0
D3.js from Excel ../../../20131214667/ ../../../20131214667/#comments Sat, 14 Dec 2013 07:37:39 +0000 http://xfra.me/?p=667 前回、Excelデータのビジュアライズに、WebViewのバージョンの関係によりD3.jsでなくjqplotを使用しましたが、Selenium IDEを使うと、WebViewでなくWebブラウザを使用できるので、これならD3.jsでもと思い、トライしてみました。

このツールはWebアプリのテスト等に使うもので、ブラウザ操作を自動的にできるなどとても強力なツールです。また各種プログラムコードも出力してくれます。

selenium-vba

https://code.google.com/p/selenium-vba/

ここではVBAからseleniumアドインを組み込んだFirefoxをコントロールする方法でテストしました。これならVBAからFirefoxで表示されているページのJavaScriptを呼び出すことができます。

環境 : SeleniumWrapperSetup-1.0.16.0.exe, Firefox 23.0.1, Excel 2010 / Windows 7
Excel Visual Basic for Application -> ツール -> 参照設定で、SeleniumWrapper Type Library を追加

Private Sub CommandButton1_Click()
   Dim selenium As New SeleniumWrapper.WebDriver
   selenium.Start "firefox", "file:///C:\d3.html"
   selenium.Open "file:///C:\d3.html"
   For i = 1 To 20
       v1 = Sheets(1).Cells(i, 1).Value
       v2 = Sheets(1).Cells(i, 2).Value
       v3 = Sheets(1).Cells(i, 3).Value

       selenium.getEval "setData({'clm1':" + Str(v1) + ", 'clm2':" + Str(v2) + ", 'clm3':" + Str(v3) + "});"
   Next i
   selenium.getEval "plot();"
End Sub

d3_2

D3.jsは以下のサンプルを使いました。

http://bl.ocks.org/mbostock/raw/7586334/

d3_1

サンプルでは、csvからファイルを読み込むようになっていますが、これを以下のように変更しました。
d3.html抜粋

var cars = [];
function setData(d)
{
	cars.push(d);
}
function plot(){
  x.domain(dimensions = d3.keys(cars[0]).filter(function(d) {
    return d != "name" && (y[d] = d3.scale.linear()
        .domain(d3.extent(cars, function(p) { return +p[d]; }))
        .range([h, 0]));
  }));
 .....
}
.....

Firefoxにもアドインを入れておく必要があります。
SeleniumIDE
これはなかなかいいかも。

]]>
../../../20131214667/feed/ 0
jQueryPlot from Excel ../../../20131207651/ ../../../20131207651/#comments Sat, 07 Dec 2013 14:35:10 +0000 http://xfra.me/?p=651 データビジュアライゼーション。最近とてもブームでもあり私自身も大変興味深い領域です。Excelデータをビジュアライゼーションするとき、どんな形が面白そうかと考えてみたところ、WebでJavaScriptライブラリという結論になりました。Webで表示させるためには、VSTOを使ってWindowsForm上のWebViewにhtmlファイルを読み込ませる方法にしました。もともと今大人気のD3.jsを使いたかったのですが、WebViewがIE7相当のため(Webサーバログで確認)動作しませんでした。対応しないメソッドがあったり、SVGを使うということが原因と思われます。(ちなみにQtのQWebViewでは表示できました。)しかしながら個人的にこのD3.jsを初めて知ったときは、jQueryが登場したときと同じくらい衝撃を受けました。ちょっとはまっています。
そこでD3.jsのかわりにIE7にも対応しているjQueryPlot(http://www.jqplot.com/)を使うことにしました。

前置きが長くなりましたが、ExcelシートにあるデータをWindowFormのボタンを押すとWebViewのグラフが更新されるデモをつくってみました。

jqplot1

jqplotdata1

データを変更(赤字部分)してボタン押下

jqplot2

jqplotdata2

環境 : VisualStudio 2010, Excel 2010 / Windows 7
ThisWorkbook.cs

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.Linq;
using Microsoft.Office.Tools.Excel;
using Microsoft.VisualStudio.Tools.Applications.Runtime;
using Excel = Microsoft.Office.Interop.Excel;
using Office = Microsoft.Office.Core;

namespace ExcelWorkbook_Web
{
    public partial class ThisWorkbook
    {
        private void ThisWorkbook_Startup(object sender, System.EventArgs e)
        {
            Form1 fm = new Form1();
            fm.Show();
        }
        public String getData()
        {
            String str = "[";

            for (int i = 1; i <= 7; i++)
            {
                str += "[";

                var o1 = Globals.Sheet1.Cells[i, 2].Value;
                var o2 = Globals.Sheet1.Cells[i, 3].Value;
                var o3 = Globals.Sheet1.Cells[i, 4].Value;

                str += o1.ToString() + "," + o2.ToString() + "," + o3.ToString();
                var o4 = Globals.Sheet1.Cells[i, 1].Value;
                str += ",'" + o4.ToString() + "'";
                str += "]";
                if (i != 7)
                {
                    str += ",";
                }
            }
            str += "]";
            return str;
        }

        private void ThisWorkbook_Shutdown(object sender, System.EventArgs e)
        {
        }

        #region VSTO デザイナーで生成されたコード
        private void InternalStartup()
        {
            this.Startup += new System.EventHandler(ThisWorkbook_Startup);
            this.Shutdown += new System.EventHandler(ThisWorkbook_Shutdown);
        }
        #endregion
    }
}

Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ExcelWorkbook_Web
{
    [System.Runtime.InteropServices.ComVisibleAttribute(true)]
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            webBrowser1.ObjectForScripting = this;
            webBrowser1.Navigate(new Uri("file:///C:/work/test.html"));

        }

        private void button1_Click(object sender, EventArgs e)
        {
            String str = Globals.ThisWorkbook.getData();
            object[] args = {str};
            webBrowser1.Document.InvokeScript("plot", args);
        }
    }
}

test.html

<html>
<head>
<!--[if lt IE 9]><script language="javascript" type="text/javascript" src="excanvas.js"></script><![endif]-->
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="jquery.jqplot.min.js"></script>
<script type="text/javascript" src="jqplot.bubbleRenderer.min.js"></script>
<link rel="stylesheet" type="text/css" href="jquery.jqplot.min.css" />
<script>
function plot(arg)
{
    var arr = eval(arg);

    plot1 = $.jqplot('chart1',[arr],{
        title: 'Transparent Bubbles',
        seriesDefaults:{
            renderer: $.jqplot.BubbleRenderer,
            rendererOptions: {
                bubbleAlpha: 0.6,
                highlightAlpha: 0.8
            },
            shadow: true,
            shadowAlpha: 0.05
        }
    });
}
</script>
</head>
<body>
<div id="chart1" style="height:300px;width:300px; "></div>
</body>
</html>

Excelシートのデータを変更してボタンを押すと、BubbleChart(というらしい)が変化する模様は、なかなかわかりやすいくて使いやすいと思いました。
いろいろと応用がききそうです。

]]>
../../../20131207651/feed/ 0
Apps for Office ../../../20131104603/ ../../../20131104603/#comments Mon, 04 Nov 2013 12:14:50 +0000 http://xfra.me/?p=603 VisualStudio 2013のプロジェクトテンプレートに、Office 2013用アプリというテンプレートがC#の下にあります。
これを以下のサイトを参考に、Apps for Officeをつくってみました。(Excel)

How to: Create your first task pane or content app by using Visual Studio

http://msdn.microsoft.com/library/office/fp142161%28v=office.15%29

その前に、これに取り組もうと思ったのは、なんとJavaScriptでExcelのCellを読み書きできてしまうからです。どのように使うものなのかということより、まずこれを試したかったからです。
(しかしいつもネーミングが汎用的でわかりづらいですね。(ストアアプリとかも) 日本語だとOfficeアプリ? Office Web Appsと似ている・・など、もう少し機能が明確化できる名前だといいのですが。)

Office用アプリの作成で、「Excelのコンテンツアプリ」を選びました。参考サイトとは違うのですが、作業ウィンドウという特別なところにおかれるのではなく、画像やグラフのように任意の場所に置きたかったからです。
oa1

環境 VisualStudio 2013, Office 2013 / Windows 8.1
Home.js

(function () {
    "use strict";
    Office.initialize = function (reason) {
        $(document).ready(function () {
            app.initialize();

            $('#btnWrite').click(writeText);
            $('#btnRead').click(readText);
        });
    };
    function writeText() {
        Office.context.document.setSelectedDataAsync($('#wtest').text(),
            function (asyncResult) {
                if (asyncResult.status === "failed") {
                    $('#result').text(asyncResult.error.message);
                }
            }
        )
    }
    function readText() {
        Office.context.document.getSelectedDataAsync("matrix",
            function (asyncResult) {
                if (asyncResult.status === "failed") {
                    $('#result').text(asyncResult.error.message);
                }
                else {
                    $('#rtest').text(asyncResult.value);
                }
            }
        );
    }
})();

Home.html

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
    <title></title>
    <script src="../../Scripts/jquery-1.9.1.js" type="text/javascript"></script>

    <link href="../../Content/Office.css" rel="stylesheet" type="text/css" />
    <script src="https://appsforoffice.microsoft.com/lib/1.0/hosted/office.js" type="text/javascript"></script>

    <link href="../App.css" rel="stylesheet" type="text/css" />
    <script src="../App.js" type="text/javascript"></script>
    <script src="../Visualization.js" type="text/javascript"></script>

    <link href="Home.css" rel="stylesheet" type="text/css" />
    <script src="Home.js" type="text/javascript"></script>
</head>
<body>
    <center><h3>Apps for Office Test</h3></center>
    <button id="btnWrite">Write Text</button>
    <button id="btnRead">Read Text</button>
    <div id="wtest">123456789</div>
    <div id="rtest">---</div>
    <hr />
    <div id="result">message : </div>
</body>
</html>

デフォルトでjQueryサポートです。最近つかいまくってますね。またC#のプロジェクトなのにC#はどこにもでてきません。

初期画面
oa2

‘Write Text’をクリック(表示領域をあらかじめ選択してからも可。コードを変更して配列を書き込むことも可)
そして選択箇所そのままで’Read Text’をクリック
oa3

値を入力後、範囲を指定して’Read Text’をクリック
oa4

範囲を指定して’Write Text’をクリック
oa5
配列を書き込むようにしていないのでエラー

オフラインローカルのExcelファイルとしては使えないみたいですが(まだ調査不足ですが)、それがちょっと残念です。(ExcelシートにWebViewが埋め込まれ、相互データ連携ができると、Webの柔軟性からかなり用途が広がるのですが)
でもなかなか面白い機能です。

(追記:2014/09/27)SharePointに登録して、Officeアプリとして挿入が可能。

]]>
../../../20131104603/feed/ 0
Haskell from Excel ../../../20131103582/ ../../../20131103582/#comments Sun, 03 Nov 2013 14:27:02 +0000 http://xfra.me/?p=582 HaskellのモジュールをExcelから呼び出す方法がかかれたBlogをみつけたので、実際に自分の環境でやってみました。

Calling Haskell from Excel

http://flxldn.tumblr.com/post/163596541/calling-haskell-from-excel

しかし環境が違うためか、残念ながらできませんでした。せっかくなので覚えとして書きたいと思います。
(いろいろやってみてXLLアドインの勉強にはありましたが・・)

C++からHaskellの呼び出し、ExcelからのC++(XLL)呼び出しはできますが、つなげると以下のようなアラートがでました。
xllError
XLLは、xlw(A Wrapper for the Excel API)を使う方法と、Excel 2010 XLL SDKを使う方法と、二通りやりました。

参考)
xlw :

http://xlw.sourceforge.net/

http://d.hatena.ne.jp/teramonagi/20110124/1295866787

xll sdk:

http://www.microsoft.com/en-us/download/details.aspx?id=20199

テスト環境 Excel 2010 + xlw ver5, Visual Studio 2010 / Windows 7

まずHaskellソースからDLLを作成します。
addr.hs

module Adder where 

adder :: Int -> Int -> IO Int --gratuitous use of IO 
adder x y = return (x+y) 

foreign export stdcall adder :: Int -> Int -> IO Int

adder.h

#ifdef __cplusplus
extern “C”
{
#endif
__declspec(dllexport) void __stdcall HsBegin(void);
__declspec(dllexport) void __stdcall HsEnd(void);
__declspec(dllexport) long __stdcall adder(long x, long y);
#ifdef __cplusplus
}
#endif

adder.def

LIBRARY Adder
EXPORTS
adder@8=_adder
HsBegin@0=_HsBegin
HsEnd@0=_HsEnd

dllMain.c

static char* args[] = {"ghcDll" , NULL };

BOOL STDCALL DllMain( HANDLE hModule, DWORD reason, void* reserved)
{  return TRUE;}
__stdcall void HsBegin()
{
startupHaskell(1, args, __stginit_Adder);
}
__stdcall void HsEnd()
{
hs_exit();
}

以下コンパイル手順です。(VisualStudio2010コマンドプロンプト)

ghc -static -c adder.hs -fglasgow-exts
ghc -static -c dllMain.c
ghc -static -shared -o adder.dll adder.o adder_stub.o dllMain.o
lib /MACHINE:x86 /DEF:adder.def /OUT:adder.lib /NOLOGO /SUBSYSTEM:WINDOWS

出力されたadder.dllはSystem32フォルダにコピーします。

次に、XLLファイルを作成します。
xlwのインストールディレクトリの中にあるxlwTemplateExtractor.exe実行すると、XLL_Projectというフォルダがマイドキュメントに作成されるので、ここにあるソリューションを開きます。
デフォルトのEchoShortの下に追加して以下のようになります。

#include<cppinterface.h>

#ifdef __cplusplus
extern "C"
{
#endif
__declspec(dllexport) void __stdcall HsBegin(void);
__declspec(dllexport) void __stdcall HsEnd(void);
__declspec(dllexport) long __stdcall adder(long x, long y);
#ifdef __cplusplus
}
#endif

#pragma warning (disable : 4996)

short // echoes a short
EchoShort(short x // number to be echoed
           )
{
    return x;
}

short funcAdd(short d1, short d2){
 return adder(d1, d2);
//return d1 + d2;
}

cppinterface.hにはfuncAddのプロトタイプを追加します。
xlwWrapper.cppというソースは自動で生成されるようです。
adder.libを参照するようにします。

まずコメントしてあるd1+d2で成功したことを確認してから、adderのテストしました。
すると上記アラートがでます。
ここで、HsBegin、HsEndを使い方を元のブログを見てみると、ライブラリ自体のmakeが必要のようだったのであきらめ、次にXLL SDKをテストしました。(ライブラリを変更してもたぶん結果は同じという気もしましたし)

XLL SDKをインストールしたフォルダ内にある、EXAMPLEプロジェクトを使用します。
他の関数を参考にして、


#define rgFuncsRows 30

static LPWSTR rgFuncs[rgFuncsRows][7] = {

....
	{L"CalcCircum",					L"BB", L"CalcCircum"},
	{L"funcAdd",					L"III", L"funcAdd"}
};

....
__declspec(dllexport) double WINAPI CalcCircum(double pdRadius)
{
	return pdRadius * 6.283185308;
}
__declspec(dllexport) short WINAPI funcAdd(short x, short y)
{
	return (short)adder((long)x,(long)y);
	//return x + y;
}

このソースのxAutoOpen()、xAutoClose()にそれぞれHsBegin()、HsEnd()を追加。これらとadderの宣言部もxlwと同様に追加。

これもreturn x+yで動作確認後、Haskell呼び出し部をテストしました。それで上記アラートが出ました。
Excel-DNAてadder.dllを、とも思いましたが、あれはマネージDLLでした。
成果が何もないのもなんなので、cppコンソールアプリでHaskell呼び出しをしてみました。(adder.dllはexeと同じところに置く)

#include "stdafx.h"

#ifdef __cplusplus
extern "C"
{
#endif
__declspec(dllexport) void __stdcall HsBegin(void);
__declspec(dllexport) void __stdcall HsEnd(void);
__declspec(dllexport) long __stdcall adder(long x, long y);
#ifdef __cplusplus
}
#endif

int _tmain(int argc, _TCHAR* argv[])
{
	HsBegin();
	printf("adder : %d\n", adder(1,2));	
	HsEnd();	
	getchar();
	return 0;
}

3 を表示します。

また解決したらつづきを書きたいと思います。

]]>
../../../20131103582/feed/ 0
Pyvot / Excel ../../../20131019546/ ../../../20131019546/#comments Fri, 18 Oct 2013 16:30:34 +0000 http://xfra.me/?p=546 Excelネタが続きますが、今回はPythonを使ったExcel操作です。Excel「ファイル」への読み書きを目的にしたものではなく、開いたままのシートに対してリアルタイムに読み書きするものです。Pythonはソースを見やすいようにパッケージの形にしましたが、コンソールでの操作を想定しています。
コンソール画面でプログラムのテストしたりするときに、標準入力や標準出力をセルでやると面白いかもということで試してみました。WindowsやLinuxなどのコマンドラインでデータの入出力をするときなど、ファイルでもいいのですが、データを部分的に変更したりするとき、この方法は便利です。視覚的にもわかりやすいです。(こんな用途かぎられるかもしれませんが・・)

環境 : Python 2.7.3, Excel 2010 / Windows 7
インストール :

http://pytools.codeplex.com/wikipage?title=Pyvot

PTVSからもできるようですが、よくわかりませんでしたので、

https://pypi.python.org/pypi/Pyvot

こちらのサイトから
Pyvot-0.1.2-py2.7.egg
をダウンロードして、easy_install コマンドを使いました。
あとwin32comも必要です。

使い方に関しては、以下の動画がわかりやすかったです。

基本的な機能を使ってみました。
pyvot_1
Pythonから書き込んだあと、Excelシートをエディトして(1 -> 10)、Excelから読みこみます。(w.get())
Pyvot_2
これを踏まえて、ちょっと変わった使い方ですが連続してデータをExcelに送り、グラフを表示してみました。

import xl
import threading
import time
import random

def main():
	xl.Workbook('xlTest.xlsx')
	
	r = range(1,11)
	for i in range(10):
		xl.get("A1:A10").set(r)
		random.shuffle(r)
		time.sleep(1)

if __name__ == '__main__':
	main()


初期値は以下で、
PYvot_3
あとは1秒ごとにランダムに並び順が変化します。
Pyvot_4
実は、マルチスレッドでデータを変化させ、リアルタイム解析みたいなことができないか、ということをしたかったのですが、Pythonのスレッドの中からxl関数を呼び出すと、エラーになってしまいました。また前提条件として、プログラム動作中、セルをクリックすると停止します。あと変更対象のセルにはあらかじめデータを入れておく必要があります。
自分が個人的にやりたかったことができないものもありましたが、十分使えるツールだと思います。

また、いろいろと試していきたいと思います。

]]>
../../../20131019546/feed/ 0
Excel と R via VSTO ../../../20131013539/ ../../../20131013539/#comments Sun, 13 Oct 2013 07:35:47 +0000 http://xfra.me/?p=539 RExcelアドインを使ってExcelとR連携は前々回テストしましたが、VSTOを使ってRを呼び出すテストをしてみました。
これには、“C#, Python で R.NET”でテストしたR.NETを使います。
プロジェクトは“LINQ/VSTO”と同じ方法で作成します。

環境: Excel2010, R 3.0.0 / Windows 7
VisualStudio 2010 参照設定追加
RDotNet
RDotNet.NativeLibrary

using System;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using RDotNet;
using Excel = Microsoft.Office.Interop.Excel;

namespace ExcelWorkbook3
{
    public partial class Sheet1
    {
        private void InternalStartup()
        {
            DataTable table = new DataTable();
            Excel.Worksheet activeSheet = ((Excel.Worksheet)Application.ActiveSheet);

            var envPath = Environment.GetEnvironmentVariable("PATH");
            var rBinPath = @"C:\Program Files\R\R-3.0.0\bin\i386";
            Environment.SetEnvironmentVariable("PATH", envPath + Path.PathSeparator + rBinPath);
            using (REngine engine = REngine.CreateInstance("RDotNet"))
            {
                engine.Initialize();

                StringBuilder plotCommmand = new StringBuilder();  
                plotCommmand.Append(@"rnorm(100)");
                var e = engine.Evaluate(plotCommmand.ToString());
                int k = 1;
                foreach (var v in e.AsNumeric().ToArray<double>())
                {
                    activeSheet.Cells[k, 1].Value = v;
                    k++;
                }
            }
        }
    }
}

R側では正規分布の乱数を生成するrnorm関数を使い、その出力をExcelシートに表示させます。Excel側では、グラフ表示をして正規分布を確認しました。(手動)
(ちなみにRのPlotを呼び出すこともできます)
R_VSTO1
このような単純な例では、どんな連携方法も大差ありませんが、その他に組み合わせるものがある場合、いろいろと解決方法を知っておくと便利です。

]]>
../../../20131013539/feed/ 0
Excel Add-Ins in Python, PyXLL ../../../20131013527/ ../../../20131013527/#comments Sat, 12 Oct 2013 15:24:37 +0000 http://xfra.me/?p=527 前々回の投稿のExcel-DNAのホームページを見ていると、PythonでExcelと連携するPyXLLというものの存在をしりました。
Pythonが主でExcelシートを操作できるライブラリもありますが、Excelが主でPythonをバックエンドで使えるというメリットは、それ以上の広がりがあると思いテストしてみました。

環境 : PyXLL ver2.0.4, Excel 2010 / Windows 7
Download : http://www.pyxll.com/index.html

from pyxll import xl_func

@xl_func("var[] nnn: var[]")
def testFunc1(nnn):
	res = []
	for nn in nnn:
		r = []
		for n in nn:
			n = n * n
			r.append(n)
		res.append(r)
	return res
	

元のマトリックスの要素を自乗します。
pyxll1

Excel-DNAのときと同様、この状態で CTL + SHIFT + Enter を押します。

pyxll2

Excel-DNAの手軽さでPythonが使える、それだけでも魅力ですが、データ操作をPythonでできるというのは、生産性が高くなります。

]]>
../../../20131013527/feed/ 0