<   2015年 12月 ( 2 )   > この月の画像一覧

VBA死滅せよ

営業さん向けのツールで、よくExcelのマクロ組むことがあるんですが
前職でバリバリのソリューションやってた自分はもうVBAをガチ実装します。
可視性のあるVBEで自分で書いた方が間違わないし、色々出来るし。

で、今さっき見つけた変な動き
e0349767_16595738.png
空文字(未入力)ならエラーを出して処理を中断するチェックなんだけも
なぜか空なのにif文の中に入らない。
なぜ???

ウォッチ式を見てみる。
e0349767_17043073.png
値はEmptyなのでif文の評価はTrueにならないとおかしいのだが・・・
もう少し細かく評価してみる。
e0349767_17061793.png
んん??値が""になった??

ということは・・・if文全体の評価をウォッチしてみる。
e0349767_17083738.png
案の定、まさかのFalse

型をよく見てみるとTrimした段階でVariant/Emptyから
Variant/Stringに変わっている。

調べたところによると、Trimに限らず文字列を返す関数ってのはVariantを引数として渡すと、内部処理形式をStringで返す、しかもエラーとして処理されない
ということらしい。

だからVariantは嫌いなんだ!

[PR]
by onigirism | 2015-12-25 17:17 | プログラミング | Comments(0)

SmoothingFilter拡張

以前書いたPointの平滑化をさらに拡張、
一度インスタンスを作れば各JointType全てに平滑処理が走るように実装してみた。
でもコレの違いってやってる人じゃないと分かんないかもしれない。
個人的にはかなりヌルヌル動いてて結果に満足だけど・・・。

以下ソース

using System;
using System.Windows;
using System.Collections.Generic;
using Microsoft.Kinect;

namespace Microsoft.Samples.Kinect.BodyBasics
{
class SmoothingPoint
{
private static Dictionary<JointType, Queue<Point>> pointBufferS = new Dictionary<JointType, Queue<Point>>();
private static Dictionary<JointType, Queue<Point>> pointBufferE = new Dictionary<JointType, Queue<Point>>();

public SmoothingPoint()
{
foreach (JointType jt in Enum.GetValues(typeof(JointType)))
{
pointBufferS.Add(jt, new Queue<Point>());
pointBufferE.Add(jt, new Queue<Point>());
}
}

public Point Smoothing(JointType jType, Point p)
{
return DoubleMovingAverage(jType, p);
}

private Point SimpleAverageFilter(JointType jt, Point newPoint, int parameter)
{
pointBufferS[jt].Enqueue(newPoint);
if (pointBufferS[jt].Count <= parameter)
{
return newPoint;
}
pointBufferS[jt].Dequeue();
Point[] list = pointBufferS[jt].ToArray();
Point point = new Point();
double x = 0;
double y = 0;

int n = pointBufferS[jt].Count;
for (int i = 0; i < pointBufferS[jt].Count; i++)
{
Point p = list[i];
x += p.X;
y += p.Y;
}
point.X = x / n;
point.Y = y / n;

return point;
}

private Point DoubleMovingAverage(JointType jt, Point newPoint, int parameter = 5)
{
Point newSimpleAverage = SimpleAverageFilter(jt, newPoint, parameter);
pointBufferE[jt].Enqueue(newSimpleAverage);
if (pointBufferE[jt].Count <= parameter)
{
return newSimpleAverage;
}
pointBufferE[jt].Dequeue();
Point[] list = pointBufferE[jt].ToArray();
Point point = new Point();
double x = 0;
double y = 0;

int n = pointBufferE[jt].Count;
for (int i = 0; i < pointBufferE[jt].Count; i++)
{
Point p = list[i];
x += p.X;
y += p.Y;
}
point.X = x / n;
point.Y = y / n;

return point;
}
}
}


[PR]
by onigirism | 2015-12-10 18:26 | C# | Comments(0)