Quantcast
Channel: 午後わてんのブログ
Viewing all 420 articles
Browse latest View live

WPFとVB.NET、エクセルのグループ化とグループ化解除を真似したい5

$
0
0

グループ化テストの続き
テストのテスト
グループ化後の回転
エクセルの場合
イメージ 2
グループの中心が回転軸になっている
これを真似したい

イメージ 1
同じ色どうしがグループ化されていると見倣して、グループを回転させた時の動作
水色のThumbの回転軸は自身の中心
桃色のThumbの回転軸も自身の中心だけど、回転軸のセットを押すと2つのThumbの中央に切り替わる、エクセルと同じなのはこちら


デザイン画面とXAML
イメージ 3


VBコード
イメージ 4

Imports System.Windows.Controls.Primitives


Class MainWindow
    Private g1 As New List(Of Thumb) 'グループ1
    Private g2 As New List(Of exThumb) 'グループ2

    '中心点位置取得
    Private Function GetCenterPoint(t As Thumb) As Point
        Dim gt As GeneralTransform = t.TransformToVisual(canvas1)
        Dim cp As New Point(t.Width / 2, t.Height / 2)
        Dim np As Point = gt.Transform(cp)
        Return np
    End Function

    Private Sub SetLocate(t As Thumb, p As Point)
        Canvas.SetLeft(t, p.X)
        Canvas.SetTop(t, p.Y)
    End Sub

    'RenderTransform用のTransformGroup
    Private Function GetTransformGroup() As TransformGroup
        Dim tg As New TransformGroup
        With tg.Children
            '追加する順番大事
            .Add(New ScaleTransform(1, 1))
            .Add(New SkewTransform)
            .Add(New RotateTransform(0))
            .Add(New TranslateTransform)
        End With
        Return tg
    End Function

    'Thumbを配置
    Private Function AddThumb(p As Point) As Thumb
        Dim t As New Thumb
        With t
            .Width = 50
            .Height = 50
            .Background = Brushes.Cyan
            .RenderTransform = GetTransformGroup()
            .RenderTransformOrigin = New Point(0.5, 0.5)
        End With
        Call SetLocate(t, p)
        canvas1.Children.Add(t)
        Return t
    End Function

    'ExThumbを配置
    Private Function AddexThumb(p As Point) As exThumb
        Dim t As New exThumb
        With t
            .Width = 50
            .Height = 50
            .Background = Brushes.Pink
            .RenderTransform = GetTransformGroup()
            .RenderTransformOrigin = New Point(0.5, 0.5)
        End With
        Call SetLocate(t, p)
        canvas1.Children.Add(t)
        Return t
    End Function

    'exThumbのRect取得
    Private Function GetRect(t As exThumb) As Rect
        Dim gt As GeneralTransform = t.TransformToVisual(canvas1)
        Dim r As Rect = gt.TransformBounds(New Rect(New Size(t.Width, t.Height)))
        Return r
    End Function

    '渡されたすべてのRectが収まるRectを取得
    Private Function GetGroupRect(rl As List(Of Rect)) As Rect
        '左上と右下の座標を探す、これで位置とサイズが分かる
        Dim minX As Double = rl(0).X
        Dim minY As Double = rl(0).Y
        Dim maxX As Double = minX + rl(0).Width
        Dim maxY As Double = minY + rl(0).Height
        Dim r As Rect
        For i As Integer = 1 To rl.Count - 1
            r = rl(i)
            minX = Math.Min(minX, r.X)
            minY = Math.Min(minY, r.Y)
            maxX = Math.Max(maxX, r.X + r.Width)
            maxY = Math.Max(maxY, r.Y + r.Height)
        Next
        '座標からRect作成
        r = New Rect(minX, minY, maxX - minX, maxY - minY)
        Return r
    End Function


    Private Sub haiti()
        '各Thumbを配置
        g1.Add(AddThumb(New Point(50, 100)))
        g1.Add(AddThumb(New Point(150, 100)))

        g2.Add(AddexThumb(New Point(300, 100)))
        g2.Add(AddexThumb(New Point(400, 100)))

    End Sub


    'アプリ起動して描画完了後
    Private Sub MainWindow_ContentRendered(sender As Object, e As EventArgs) Handles Me.ContentRendered
        Call haiti()
    End Sub

    '普通に回転
    Private Sub bt1_Click(sender As Object, e As RoutedEventArgs) Handles bt1.Click
        For Each t As Thumb In g1
            Dim ro As New RotateTransform(15) '15度回転
            Dim tg As TransformGroup = t.RenderTransform
            tg.Children.Add(ro)
        Next
    End Sub

    'グループ化後の範囲を考慮して回転
    Private Sub bt2_Click(sender As Object, e As RoutedEventArgs) Handles bt2.Click
        For Each t As exThumb In g2
            '回転軸を指定して15度回転
            Dim ro As New RotateTransform(15, t.TransformAxis.X, t.TransformAxis.Y)
            Dim tg As TransformGroup = t.RenderTransform
            tg.Children.Add(ro)
        Next
    End Sub


    '回転軸のセット
    Private Sub bt3_Click(sender As Object, e As RoutedEventArgs) Handles bt3.Click
        Dim rl As New List(Of Rect)
        For Each t As exThumb In g2
            '中心点のセット
            t.CenterPoint = GetCenterPoint(t)
            rl.Add(GetRect(t))
        Next
        Dim r As Rect = GetGroupRect(rl)
        Dim x As Double = r.Width / 2 + r.Left
        Dim y As Double = r.Height / 2 + r.Top
        Dim cp As New Point(x, y) 'グループ化後の中心点
        'グループ化後の回転軸のセット
        For Each t As exThumb In g2
            t.GroupCenterPoint = cp
            Dim np As Point = t.GroupCenterPoint - t.CenterPoint
            t.TransformAxis = np '回転軸のセット
        Next
    End Sub


    Private Sub bt4_Click(sender As Object, e As RoutedEventArgs) Handles bt4.Click
        g1.Clear()
        g2.Clear()
        canvas1.Children.RemoveRange(0, 4)
        haiti()
    End Sub
End Class


Public Class exThumb
    Inherits Thumb
    Public Property CenterPoint As Point '自身の中心点
    Public Property GroupCenterPoint As Point 'グループ範囲の中心点
    'グループ化後の範囲を考慮して回転するときに使う回転軸用
    Public Property TransformAxis As Point

End Class





WPFでのコントロールの描画位置、レイアウトはRenderTransformを指定する
回転や拡大率などの変形もRenderTransformにそれぞれのTransformを指定する
拡大して回転とかの複数の変形をする場合はTransformのCollectionを作って
TransformGroupのChildrenに追加する感じになる
Dim tg As New TransformGroup
tg.Children.Add(New ScaleTransform(2,2))'縦横2倍に拡大
tg.Children.Add(New RotateTransform(15))'15度回転
Thumb.RenderTransform = tg

回転軸は特に指定しないと左上が軸になるので自身の中心を軸にする場合は
コントロールのRenderTransformOriginプロパティに Point(0.5,0.5)を指定する
Thumb.RenderTransformOrigin = New Point(0.5,0.5)

これが基本になって
ここからさらに回転させるときは
A:自身のRenderTransformの中からRotateTransformを探しだして、その中のAngleプロパティを変更する
B:新たにRotateTransformを作って自身のRenderTransformのGroupに追加する
このどちらかになると思う

Aはムダがないけどちょっとめんどくさい
Bはラクだけど回転の変更する度に追加するからかなりのムダ、きりがない
きりがないけど今回は回転軸の変更が目的だから妥協してこちらを採用



回転軸用のプロパティを持ったThumb
イメージ 5
グループ化後は回転軸を変更するので、その軸の位置をThumb自身に持たせるためにThumbを継承したexThumbって名前をつけたClassを作成
軸の位置はTransformAxisって名前をつけた
その他のCenterPointとGroupCenterPointは確認用


イメージ 6
自身の中心点を取得するのにTransformToVisualを使っているけど
Canvas.GetLeftとCanvas.GetTopを使って左上の位置を取得してから、自身のサイズから計算するのもあるなあ

グループ化後の回転軸の位置
イメージ 8
グループのサイズの中心位置 - グループ化前の自身の中心点位置(133行目)
これがグループ化後の回転軸の位置TransformAxisになる(134行目)

グループ化後の回転
イメージ 7
TransformAxisを使って回転軸を指定したRotateTransformを作成(112行目)
RenderTransformにRotateTransformを追加


今回の方法ではきりがない
イメージ 9
回転に5回変更を加えてから一時停止してRenderTransformの中を見てみると
RotateTransformが5個ズラーっと並んでいるのがわかる


次回はこれを直すのとグループ化を解除するときの動作のテスト








WPFとVB.NET、エクセルのグループ化とグループ化解除を真似したい6

$
0
0

グループ化後の変形とグループ化解除のテスト
前回からの続き、テストばっかりで本番前に力尽きそう

イメージ 1
赤枠はグループの範囲の境界線、青マスは1マス50
見た目の位置とサイズは水色のこと
前提
グループを回転や拡大率の指定をするときの中心点は各Thumb(四角)の中心ではなくグループ範囲の中心にする

初期状態は
水色と桃色をグループ化した後にさらに黄色をグループ化した状態
グループB
┣黄色
┗グループA
┣水色
┗桃色

これを1回解除すると
グループA
┣水色
┗桃色
黄色
こうなって
もう一回解除すると

水色
桃色
黄色
ってバラバラになる

難しいのが解除した時に解除前の位置や回転や拡大率とかの変形の引き継ぎ

回転の場合
イメージ 2
変化するのは見た目だけで内部のものは変化しない
実際に位置やサイズを指定するのは内部のものになる


グループ解除で中心点の変化
イメージ 3
内部の位置を変更して見た目の位置を変化させないようにしている
って今気づいたけど見た目の位置の表示がおかしい、変化しているw
→見た目の位置取得前に再描画する必要があったみたい


デザイン画面とXAML
イメージ 4

VBのコード
イメージ 5


前回のこれ
A:自身のRenderTransformの中からRotateTransformを探しだして、その中のAngleプロパティを変更する
B:新たにRotateTransformを作って自身のRenderTransformのGroupに追加する
このどちらかになると思う

Aはムダがないけどちょっとめんどくさい
Bはラクだけど回転の変更する度に追加するからかなりのムダ、きりがない
前回はBの方法だったけど今回はまともなAの方法にすることになったけどグループ化後に回転すると位置がずれる!
これはグループ化の前後で回転軸の位置が変わるのが原因
例えば
グループ化前の時に10度回転、その後グループ化してグループを10度回転で合計20度回転
これが回転の変化で回転軸の変化が
グループ化前の回転軸は(0,0)、グループ化によって回転軸の位置が(50,30)になった場合
RotateTransform(10,0,0)から
RotateTransform(20,50,30)に変更することになるけど
これだと位置がずれる

追加方式のBなら
RotateTransform(10,0,0) + RotateTransform(10,50,30)
これならズレることはない、けど回転の変更する度に増えるから
RotateTransform(10,0,0) + RotateTransform(10,50,30) + RotateTransform(10,50,30) + RotateTransform(10,50,30) + RotateTransform(10,50,30)…
ってきりがないのは前回
なので
1回だけ追加(B方式)して、それ以降は追加したものに変更を加える(A方式)
RotateTransform(10,0,0) + RotateTransform(10,50,30)
こうして1回だけ追加して、ここからさらに10度回転して合計30度にするときは
RotateTransform(10,0,0) + RotateTransform(20,50,30)
こうする

変形用のTransformは回転以外に3つ用意されていて合計4つ
これをまとめたもの(Collection)を記録しておく入れ物が必要
同じグループ内でもThumbによって中心点は違ってくるからThumbに持たせる必要がある
ってことで前回同様Thumbを継承したクラスを作ってこんな感じになった
イメージ 6
492行目のgtCollectionがそれ、グループ化した時にScale、Skew、Rotate、Translateこの4つのTransformを作成して入れておく、変形するときはここから取り出して値を設定する
グループ化したものをさらに別のものとグループ化すると中心点も変化するから、また新しい4つのTransformを作成してgtCollectionを今のものと入れ替える
この時古い方は捨てないで取っておくとグループ化解除した時にまた使えるので、それの入れ物が493行目のgtStack
494行目は自身がどのグループに属しているかの目印用、Group2を入れておく
この辺りのStack型のCollectionの使い方は
WPFとVB.NET、エクセルのグループ化とグループ化解除を真似したい3 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14187560.html
この時と同じ感じ

Group2、グループの情報用クラス
イメージ 7
これは
WPFとVB.NET、エクセルのグループ化とグループ化解除を真似したい4 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14203583.html
この時とだいたい同じ感じ
違うのは516行目、CenterPointにはグループの中心点を記録しておく

イメージ 8
Collectionの中から取り出すときに使う
中に入っている順番は固定していてその順番に合わせてある
上から0,1,2,3
ScaleTransformを取り出したい時に
gtCollection(0)でもいいけど数値だけだとわかりにくいかなと
gtCollection(GTransform.Scale)

Thumbのグループ化
イメージ 9
グループ化するテストは
WPFとVB.NET、エクセルのグループ化とグループ化解除を真似したい4 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14203583.html
ここで終わっているので違うところは
変形に使うTransformを設定しているあたり
198行目で新たなTransformを作成、このTransformの中心軸、基準点っていうのかな、この点の位置は
グループの中心点 - 自身の中心点(197行目)
これを指定している
イメージ 10
↑水色と桃色をグループ化する場合
175,125グループの中心
125,125水色の中心
なので
175-125=50、125-125=0で
50,0
これを新しいTransformの軸に指定する
4つのTransformを作成するGetTransformGroup2
イメージ 11
これに50,0を渡すと
ScaleTransform(1,1,50,0)
とかになる
この新しいTransformを198行目でtgCollectionに入れて
200から203行目でRenderTransformに追加している(B方式)
RenderTransformの中を見てみる
イメージ 12
グループ化前の4つ(0から3)と今追加した4つ(4から7)合わせて8個入っているのがわかる
4のScaleTransformを見てみると
イメージ 13
CenterXが50、CenterYが0と指定したとおりになっている
4から7の4つ全てのCenterXとCenterYは同じになっているはず
グループを変形するときはこれらを取り出して値を指定することになる
最初はこのとり出す方法がわからなかった
グループの拡大率を変えたいときは4番のScaleTransformが目的のものになるけど
0番にもScaleTransformがあるのでScaleTransformを探すってのは使えない
追加する順番や個数は決まっているから番号を覚えておけばできるけどわかりにくい
ってことで今回の方法
イメージ 14
さっきも載せたけどgtCollection
新しく作ったTransformはこのgtCollectionとRenderTransformのTransformGroupの両方に入れる、この両方の入れ物はCollectionでCollectionに入れたものは実際の値ではなくて参照(リンクみたい)になるのでどちらかに変更があるともう片方も変更される
gtCollectionには今のグループのTransformだけを入れておくので0から3番までの4つを覚えておけばいい
これなら簡単に目的のTransformを取得できるので、こっちで取得して値を変更する、両者は参照(リンク)関係なのでRenderTransformの方も変更される

グループの回転
イメージ 15
447行目で回転のRotateTransformを取得している
gtCollectionにGTransform.Rotate(は2番)を指定して取得
448行目で角度変更
これでRenderTransformの中の今のグループに関係あるRotateTransformも変更されるので期待通りの動作になる

15度回転
イメージ 17
この時の水色のgtCollectionとRenderTransformを見てみると

gtCollectionのRotateTransform
イメージ 16
2番めのRotateTransformのAngleが15になっている

RenderTransformのRotateTransform
イメージ 18
グループ化で追加した4から7のうち6番目のRotateTransformのAngleも15になっている


グループ化解除
移動
イメージ 20
2から3へは見た目の位置に変化はないけど変化しないように移動している
2の時点では1の時と全く同じ位置にあって、回転によって見た目の位置が変化しているだけ
3でグループ化解除して単体になる黄色はグループの回転から外れるので位置を変更しないと

イメージ 21
こうなってしまう、これだと不自然なので移動させる必要がある

どのグループにも属さないで単体になるThumbの移動
イメージ 19
今(解除前)の見た目の中心位置 - 前の中心位置 = 移動距離
前の位置 + 移動距離 = 期待する位置
二度手間な感じだけどこうなった

今の見た目の中心点を取得する
GetCenterPointLocate
イメージ 22
自身の元の中心点をTransformToVisualを使って得たGeneralTransformのTransformで変換して取得している

指定した距離分移動させる
OffsetLocate
イメージ 23



1階層下のグループの中のThumbすべての移動
これも移動させないと
イメージ 24
不自然になってしまうので
イメージ 25
解除するグループ(3つのThumb)の中心点と解除後のグループ(水色と桃色)の中心点
この2つの点の差
これの分だけ移動させると自然な位置になる

グループ化解除時の
回転とかの変形(Transform)の引き継ぎと削除
イメージ 27
引き継ぎしないと位置もおかしくなるし、これを変形させるともっとおかしくなるので
引き継ぎと削除する
InheritsTransform
イメージ 26
グループ化するときに捨てないで取っておいたTransformCollectionをgtStackから取り出す(258行目)
これにそれぞれ4つの値を引き継ぐ、って今回は回転と拡大率しか使っていないから2つしか書いてなかった
回転角度は足す、拡大率は掛け算でいいみたい(271行目まで)
引き継いだら今のをRenderTransformから削除(273から276行目)
gtCollectionも入れ替える(278行目)
これをグループ化解除の移動が終わった後のここで実行している
イメージ 28
ついでに今属しているグループの目印用の変数の中も入れ替え
これでやっとグループ化解除の処理が終わる


エクセルでのグループ化→回転→グループ化解除
イメージ 29
グループ化したものを回転するとかは
めったに使わないんだよねw

エクセルでグループ化→拡大率150%
イメージ 30
エクセルの拡大率変化の基準点は中心じゃなくて左上なんだなあ

イメージ 31
今回のテストでの基準点は全て中心にしたから結果が異なる
基準点の切り替えできるようにしたいけどこのままかなあ




やっとできたグループ化解除で不自然にならないようにつじつま合わせ
以前の方法のグループ化するときにはThumbのなかにThumbを入れる、っていうのだとこれができなさそうで諦めて今のThumbはThumbのままで擬似的なグループ化っていう方法を試していたんだけど、なんとかできたっぽい

グループ化のテストは次で最後になるかなあ
前々回の範囲をマウスで指定してグループ化するのと移動を今回のに付け足す感じ


今回のコード全部
Wpf_test128_TransformGroup - Visual Studio Team Services
https://gogowaten.visualstudio.com/WPF/_git/WPF_test7?path=%2FWpf_test128_TransformGroup&version=GBmaster&_a=contents
どうやら↑ここに載っけたコードはMicrosoftのアカウントがないと見れないみたい?
GitHubとかなら誰でも見れるようなんだけど使い方がわからん
ヤフーブログの2万文字制限が無くなるか緩和してくれないかしら


前々回
WPFとVB.NET、エクセルのグループ化とグループ化解除を真似したい4 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14203583.html

前回
WPFとVB.NET、エクセルのグループ化とグループ化解除を真似したい5 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14209863.html



WPFとVB.NET、FillContainsWithDetailとGeometryを使って面と面の重なりを判定

$
0
0

エクセルのグループ化を真似したくていろいろ試している続き

マウスドラッグで四角形の範囲を作ってその範囲に重なったものを取得するっていうだいぶ前の方法
WPFとVB.NET、エクセルのグループ化とグループ化解除を真似したい4 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14203583.html

この時の方法だとコントロールを回転とか変形をさせた時にうまくいかないことがわかった(’・ω・‘)
イメージ 1
RotateTransformで回転させた後だと四隅に重ねても取得できていない
これはRotateTransformで変形させても変わるのは見た目だけで中身は変わっていないのに、その中身と判定しているから
解決するには見た目通りの形を取得する必要があるかなと思って

なんとかできたのが今回の
イメージ 2
正方形の赤が元の形で
斜めになっている長方形は元の形から横拡大率2.0、縦拡大率0.7、右に30度回転
これをいろいろな選択範囲で判定している
下のステータスバーは判定結果を表示している

ググっていたら
VisualTreeHelper.HitTestっていうのを使うのもあるみたいだったけど難しくてわからなかった(小並感)CallBackってのがわからん
だから別の方法

前回まで判定に使ったのはRectクラス、つまり長方形で判定していた
回転させると菱型になるからRectは使えないので今回はGeometryクラス

GeometryクラスのFillContainsWithDetailメソッドを使ってコントロール同士の重なりの判定をしている
この便利なメソッドFillContainsWithDetail、これにたどり着くまでが長かった
ヒントになったのがこちら
片鱗懐古のブログ: wpf : UIElement.InputHitTestを試したら予想と違った動作
http://pieceofnostalgy.blogspot.jp/2011/11/wpf-uielementinputhittest.html
ありがとうございます!


デザイン画面とXAML
イメージ 3
赤に塗ったBorderを2つ表示している
正方形のは目印用
拡大回転させた長方形のほうが目的のものになる
このふたつは見た目が違うだけで中身は同じ大きさ同じ位置

MainWindowのVBコード
イメージ 4


Class MainWindow

    Private selectPath As New Path      '選択範囲用
    Private intersectPath As New Path   '重なった場所用
    Private syokiP As Point             '最初にクリックした場所
    Private IsDrag As Boolean           'マウスドラッグ移動中判定用
    Private bRedGeometry As PathGeometry '赤BorderのGeometry


    '表示している赤Borderの見た目上のGeometryを作成、ついでにPathで黒枠表示
    Private Sub AddGeometry()
        '見た目上の四隅の位置を取得
        Dim gt As GeneralTransform = bRed.TransformToVisual(canvas1)
        Dim p0 As Point = gt.Transform(New Point(0, 0)) '左上
        Dim p1 As Point = gt.Transform(New Point(bRed.Width, 0)) '右上
        Dim p2 As Point = gt.Transform(New Point(bRed.Width, bRed.Height)) '右下
        Dim p3 As Point = gt.Transform(New Point(0, bRed.Height)) '左下

        'PathFigure作成
        Dim pf As New PathFigure
        pf.IsClosed = True '線を閉じる
        pf.IsFilled = True '塗りつぶしするにはこれをTrue、さらにPathのFillに色指定
        'FillContainsWithDetailを使って重なり判定するときはTrueにする、PathのFillは無くてもOK

        '線の追加、順番は左上、右上、右下、左下、一筆書きならどうでもいい
        pf.StartPoint = p0
        pf.Segments.Add(New LineSegment(p1, True))
        pf.Segments.Add(New LineSegment(p2, True))
        pf.Segments.Add(New LineSegment(p3, True))

        Dim g As New PathGeometry()
        g.Figures.Add(pf)
        bRedGeometry = g '赤BorderのPathGeometry完成

        'Pathを使って目印用の黒枠表示
        'PathFigureからPathGeometryを作ってPathのDataに指定
        Dim kuroWaku As New Path With {.Stroke = Brushes.Black}
        kuroWaku.Data = g
        'kuroWaku.Fill = Brushes.Blue '塗りつぶし
        canvas1.Children.Add(kuroWaku)
    End Sub

    Private Sub MainWindow_Initialized(sender As Object, e As EventArgs) Handles Me.Initialized
        canvas1.Background = Brushes.Transparent 'マウスドラッグ移動で必要
        selectPath.Stroke = Brushes.Cyan '選択枠
        'intersectPath.Stroke = Brushes.Gold
        intersectPath.Fill = Brushes.Cyan '重なり判定

    End Sub


    Private Sub MainWindow_ContentRendered(sender As Object, e As EventArgs) Handles Me.ContentRendered
        Call AddGeometry() '赤BorderのGeometry作成
    End Sub


    'マウスドラッグ移動開始
    Private Sub canvas1_MouseLeftButtonDown(sender As Object, e As MouseButtonEventArgs) Handles canvas1.MouseLeftButtonDown
        '範囲選択枠表示開始
        syokiP = e.GetPosition(canvas1)
        canvas1.CaptureMouse()
        canvas1.Children.Add(selectPath)
        tbk1.Text = ""
        tbk2.Text = ""
        intersectPath.Data = Nothing
        canvas1.Children.Remove(intersectPath)

        IsDrag = True
    End Sub

    'マウスドラッグ移動中
    Private Sub canvas1_MouseMove(sender As Object, e As MouseEventArgs) Handles canvas1.MouseMove
        If IsDrag = False Then Return
        '最初にクリックした場所と今の場所の2点を使ってRectangleGeometry作成
        Dim rg As New RectangleGeometry(New Rect(syokiP, e.GetPosition(canvas1)))
        selectPath.Data = rg '選択枠のDataにする
    End Sub

    'マウスドラッグ移動終了時
    '選択範囲枠と赤Borderの見た目上のGeometryを比較
    '2つが重なった場所を水色で塗りつぶし
    Private Sub canvas1_MouseLeftButtonUp(sender As Object, e As MouseButtonEventArgs) Handles canvas1.MouseLeftButtonUp
        canvas1.ReleaseMouseCapture()
        canvas1.Children.Remove(selectPath)
        IsDrag = False

        If selectPath.Data Is Nothing Then Return

        '重なり判定する2つのGeometry
        Dim g1 As Geometry = selectPath.Data
        Dim g2 As Geometry = bRedGeometry
        '判定
        Dim iDetail As IntersectionDetail = g1.FillContainsWithDetail(g2)
        tbk1.Text = iDetail.ToString '判定結果表示
        'IntersectionDetailが
        'Empty            重なりなし
        'FullyContains    g2のすべてはg1の中に入っている
        'FullyInside      g1のすべてはg2の中に入っている
        'Intersects       一部が重なっている
        'つまりEmpty以外なら重なっている




        'ここから下は蛇足
        Dim ex As PathGeometry = Geometry.Combine(g1, g2, GeometryCombineMode.Exclude, Nothing)
        Dim int As PathGeometry = Geometry.Combine(g1, g2, GeometryCombineMode.Intersect, Nothing)
        Dim uni As PathGeometry = Geometry.Combine(g1, g2, GeometryCombineMode.Union, Nothing)
        Dim xo As PathGeometry = Geometry.Combine(g1, g2, GeometryCombineMode.Xor, Nothing)

        '重なった部分のPathGeometryの各Pointを取得して表示
        Dim pCount As Integer = 0
        Dim tPoint As String = ""
        For Each pff As PathFigure In int.Figures
            For Each pss As PolyLineSegment In pff.Segments
                For Each pos As Point In pss.Points
                    tPoint &= $"p{pCount}({pos:0})  "
                    pCount += 1
                Next
            Next
        Next
        tbk2.Text = tPoint 'ステータスバーに表示

        '重なった部分を水色で塗りつぶし
        intersectPath.Data = int
        canvas1.Children.Add(intersectPath)

        selectPath.Data = Nothing
    End Sub


End Class



FillContainsWithDetailメソッドは2つのGeometryを渡すと重なり具合を比較して結果を返してくれる

変形させた赤Borderの見た目通りの形をしたGeometryの作成のための4頂点を取得
イメージ 6
Geometryってのは順番が付いた点の集合みたいなものかなあ、順番に従って点を直線や曲線で繋いでいくと図形ができあがる感じ
なので見た目通りのGeometryを作るには各頂点座標が必要
各頂点は元の位置から移動している、それぞれどこに移動したか取得するには
TransformToVisualで得られるGeneralTransformを使う

赤Borderは
canvas1に表示している
Transformで変形させているので
39行目で赤Borderのcanvas1に対するGeneralTransformを取得して
40行目で元の左上の頂点(0,0)をGeneralTransformのTransformメソッドを使ってどこに移動しているか取得している
赤Borderがcanvas1上のどこに表示されていても左上の頂点がどこにあるのか取得するときは(0,0)を変形させればいいみたい
同じように他の3つの頂点も取得


イメージ 5
4隅の頂点座標がわかったらこれを使ってGeometryを作る、正確にはPathGeometryを作った、この辺はよくわかっていなくて
ジオメトリの概要
https://msdn.microsoft.com/ja-jp/library/ms751808(v=vs.110).aspx
ここ見ながら書いた
大事なのはPathFigureのIsClosedとIsFilledにはTrueを指定する
IsClosedは最初の点と最後の点を直線で繋いで図形を閉じるかどうか
IsFilledは図形の閉じた内側を塗りつぶすかどうかを指定しているみたい
とくにIsFilledはTrueにしないとFillContainsWithDetailで期待通りの判定が返ってこなかった
ここまでで赤Borderの見た目通りの形をしたGeometryは完成

目印用の黒枠表示
イメージ 7
完成したGeometryは本当に期待通りの形になっているのかの確認用
Pathを作ってそのDataにGeometryを指定して表示している
赤Borderの外側の黒枠がそれ

ここからcanvas1のマウスイベントを使った
マウスドラッグ移動で範囲選択用の枠表示
Handles canvas1.MouseLeftButtonDown
イメージ 8
83行目、マウスドラッグ移動の最初の点を記録
それ以降はステータスバー表示とかの初期化

Handles canvas1.MouseMove、マウス移動中
イメージ 9
移動開始地点と今の場所の2点を使ってRectを作成
Rectを使ってRectangleGeometryを作成
それを選択範囲枠用のselectPathのDataに指定
ってそのままだな、こんなふうにGeometryにはいくつかの種類があって
RectangleGeometryはRectから簡単に作ることができる
この時点で比較する2つのGeometryは完成しているけど、今回はマウス移動中に判定しない

Handles canvas1.MouseLeftButtonUp、左クリックを離した時
マウスドラッグ終了に判定
イメージ 10
108行目までは初期化とかしているだけで判定は111行目から
2つのGeometry
selectPathはマウスドラッグで作成した選択範囲用の四角枠、そのDataにはGeometryなのでこれをg1
bRedGeometryは赤BorderのGeometry、これをg2
114行目、ここでやっとFillContainsWithDetailを使って判定
Dim iDetail As IntersectionDetail = g1.FillContainsWithDetail(g2)
これで返ってくる判定結果の種類はだいたい以下の4つ
  • Empty            重なっている部分はない
  • FullyContains    g2のすべてはg1の中に入っている
  • FullyInside      g1のすべてはg2の中に入っている
  • Intersects       一部が重なっている
今回の目的は重なりの有無だから、Emptyかそれ以外がわかればいいことになる
つまりEmpty以外なら重なっている

これはg1、g2を入れ替えて
Dim iDetail As IntersectionDetail = g2.FillContainsWithDetail(g1)
ってしても今回の目的なら同じかも


一時停止して中を見てみる
赤BorderのGeometry作成時
イメージ 11



マウスドラッグで範囲指定した時
イメージ 12
この時

イメージ 13
こうしてみると同じGeometryでもRectangleGeometryとPathGeometryでは
ずいぶん感じが違う、にもかかわらずしっかり判定してくれるFillContainsWithDetailメソッドはすごいなあ
で、この結果は

イメージ 14
こうなる
Intersectsは一部分が重なっていた判定


イメージ 15
選択範囲のすべてが赤Borderの中に入っているときは
FullyInside

イメージ 16
こんな感じで選択範囲の中に赤Borderが全て入った時は

イメージ 17
FullyContains

イメージ 18
全く重ならなかった時は

イメージ 19
Empty


イメージ 20
なんかこれだけで楽しい


ステータスバーに表示しているp0(n,n)とかは、重なり部分を水色で塗りつぶしに使っているGeometryの各頂点座標
これの処理は
イメージ 21
この辺
GeometryクラスのCombineメソッドを使うと2つのGeometryを判定(合成?)した結果のPathGeometryを返してくれる
今回使っているのが2つが重なった部分だけの形になるPathGeometryを返してくれるGeometryCombineMode.Intersect、128行目
これで得たPathGeometryをIntersectPathのDataにして水色で塗りつぶし表示
PathGeometryの中に入っている各頂点座標をp0からの連番で表示
これは
方法 : 結合したジオメトリを作成する
https://msdn.microsoft.com/ja-jp/library/ms746682(v=vs.110).aspx
ここを参照



今回のコード一式


関連記事
前回
WPFとVB.NET、エクセルのグループ化とグループ化解除を真似したい6 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14215386.html


ベランダ菜園、トマト(レッドオーレ)種まきから61日目、開花から23日目の様子、スイートバジル骨折

$
0
0
カメラ(携帯電話)が水浸しになって暫くの間写真撮れなかったので3週間ぶりの更新

スイートバジル
イメージ 1
イメージ 20
ここから2日で

イメージ 18
イメージ 19
ここまで大きくなって、この後も勢い良く伸びて大きくなったんだけど

イメージ 22
この前の強風で根本から折れ曲がってしまった
写真は立て直したあとの状態で見た目は問題なさそうだけど
根本がグラグラぐにゃぐにゃしている

イメージ 21
水を送る管が切れてしまったのか水はたくさんあるのに
だんだんしおれてきて今ではこんな状態
支柱無しで去年は台風でも大丈夫だったんだけどなあ



トマト(レッドオーレ)
イメージ 2
左B株、右A株
こうだったのが

イメージ 4
B株は第3、第4花房が開花中
A株は第1花房が開花中

B株
イメージ 3
B株は2016/06/02に開花
種まきが2016/04/02だったからちょうど2ヶ月
これが約3週間後の今日には
イメージ 7
こうなっている、期待できそうな感じ
去年はここからバリバリ割れてしまったけど今年はどうかなあ
第1花房の周辺は葉っぱが茂っているので直射日光や雨も
多少は防げているので割れない、いいね?

これが収穫できるのは7月中旬かなあって予想
積算温度
イメージ 8

積算温度=毎日の平均気温を足したもの
トマトの開花から収穫までに必要な積算温度は800から1000度必要らしい
去年の実感だと1000から1200度って感じだった
今年の開花から昨日までの積算温度は512度なので中間地点、あと500度必要
開花から昨日までの平均温度の平均温度が22.25度、この温度が明日からずーっと続くとしたら1000度を超えるのが2016/07/16になる
実際にはだんだん気温が上がるだろうから、もう少し早くなるはず


去年の初開花は2015/06/25で45日目だった
トマト(レッドオーレ)種まきから45日目で開花、定植2株目、スイートバジルの28日目 ( ガーデニング ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/13195258.html
これ見ると去年は葉っぱが小さくてスカスカ、肥料が足りなかったんだなあってのがわかる

イメージ 9
第2花房

イメージ 10
第3花房
2つ摘果した、咲いている花も勢いがないので諦めるかも

イメージ 11
第4花房
これも元気が無い感じ
葉っぱも上のほうは小さくてスカスカ
化成肥料で追肥しているんだけど回復しない


A株
イメージ 12
第1花房が開花中なんだけどやっぱり勢いが足りない
あんまり実をつけ過ぎるのはよくないかなあと

イメージ 13
第2花房が出てきたあたりで摘芯した
かわりに第1花房の下の脇芽を伸ばしてみる

挿し芽トマトとスイートバジル
イメージ 15
これが

イメージ 14
こうなった、他と比べると地味な成長
やっぱりこのプランターの土は肥料が足りない感じ

こぼれ種からのC,D株
イメージ 17
右側のD株は取り除いてC株だけにして

イメージ 16
ここまで大きくなった、A株と同じくらい
レッドオーレも固定種ではなさそうなのでどうなるかなあと育てているけど
今のところA,B株と変わらない

土の熱消毒続き
イメージ 25
右上のイチゴを処分してプランターの土を熱消毒し終わって、いまはポリポットのイチゴを処分してその土を熱消毒中

イメージ 24
(`・ω・´)汚物(センチュウ、ムカデ、ヤスデ)は消毒だー!(`・ω・´)
雨ばかり降っているから火力が足りない(’・ω・‘)


害虫
イメージ 5
イメージ 6
ニジュウヤホシテントウ(テントウムシダマシ)
今年は初めて見る、去年も来ていてちょっと葉っぱを食べるくらいでほとんど被害はないんだけど、アブラムシを食べてくれる益虫ナナホシテントウに似ているから見つけた時のガッカリ度が大きい

益虫
イメージ 23
お腹のシマシマの幅が一定じゃないからセイヨウミツバチかなあ
羽根をブンブンさせながらこの柱を歩き回っていた
何をしていたんだろう



前回
ベランダ菜園、トマト(レッドオーレ)定植、今季のいちごの収穫は終わり、環境の違いによる成長の差 ( ガーデニング ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14184929.html






復活のスイートバジル、トマトに追肥

$
0
0


根本から折れてしまったスイートバジルその後
イメージ 5
このまま枯れてしまいそうだったので

イメージ 6
適当な枝をハサミで切って挿芽してみた

イメージ 8
次の日は晴れて気温も高くてますますしおれてきた

イメージ 14
この日は雨も降っていたけどこんなで諦めていた

イメージ 15
挿し芽した方は良くなってきた
たった2日でも根が生えてくるのかしら

イメージ 23
これが今日
こうしてみるとかなり復活したんだなあ
特に何もしていないんだけどねえ

トマトと一緒のスイートバジル
イメージ 24
なかなか大きくならない

トマト(レッドオーレ)
イメージ 10
左のB株の下側だけは良さそうなんだけど、それ以外の右側のA株や中央のスイートバジルと挿し芽のトマトがいまいち元気が無いので追肥した5日後が

イメージ 26
あんまり変化ないねえ、実は大きくなっているかなあ

追肥内容
イメージ 9
油かすで追肥してみたんだけど
これはあまり効果なかったかなあ

イメージ 17
A株を上から

イメージ 18
B株を上から
どちらも葉っぱがスカスカなんだよねえ

イメージ 19
B株第3花房
咲き終わると実ること無く落ちてしまう

イメージ 20
いつもの化成肥料(8-8-8)で追肥

イメージ 25
このサイズのプランターだとトマト2株+αは植えすぎなのか、土が良くないのか
あと手持ちの肥料は草木灰と熔リン、これも入れてみるかなあ



イメージ 11
B株の第1花房の一番下側についている実の下側が腐っているのを発見!
大玉トマトだとたまになるらしいけど
中玉トマトのレッドオーレでもなる
去年も200個くらいのうち3個くらいこうなった

イメージ 12
簡単にポロッと取れた

イメージ 13
腐っている、カビとかかなあ

イメージ 16
去年はある程度大きくなってから雨に当たるとよく割れていたけど
今年は今のところ大丈夫

こぼれ種からのC株
イメージ 22
第1花房
元気ない感じだけどだんだん実が大きくなってきた

いちご
イメージ 21
ランナーがいっぱい伸びている







枯れ葉そっくりのアカエグリバっていう蛾
イメージ 1
トマトの支柱にいた、初めて見たかも

イメージ 2
尻尾側

イメージ 3
下が頭、枯れ葉にしては分厚いねw

イメージ 4
写真撮りづらい位置
狭いところに潜り込んで写真撮ろうとすると引っかかるのがクモの巣

蜘蛛
イメージ 7
今ぐらいの時期が一番多い
害虫も取っれくれそうだからそのままにしておきたいけど
そこは邪魔だよwって時もあるからね

前回
ベランダ菜園、トマト(レッドオーレ)種まきから61日目、開花から23日目の様子、スイートバジル骨折 ( ガーデニング ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14244607.html#14244607


ベランダ菜園、トマトが赤くなってきた、7月に入ってから暑い

$
0
0

トマト(レッドオーレ)左がB株、右がA株
イメージ 1
これが2日後には

イメージ 2
イメージ 3
こうなって、さらに2日後の今日(昨日)には

イメージ 4
イメージ 5
ここまで赤くなった!
開花から34日目で昨日までの積算温度は785度
予想収穫日は7月16日だけど早くなりそう

B株第3花房
イメージ 20
ここは2つしか実らないかなあ、たぶん肥料不足

B株第4花房
イメージ 19
実ってはいるけど期待薄
B株はこの第4花房の上で摘芯してある

A株第1花房
イメージ 8
イメージ 9
相変わらず実は大きくならないけど
脇芽は伸びてきて

イメージ 10
花も咲きそう
A株は第1花房の上で摘芯してある

A,B株の間にあるスイートバジルと挿し芽トマト
イメージ 7
バジルは右半分が枯れてきた、葉っぱもポロッと取れてしまうものがある
挿し芽トマトもほとんど大きくなっていない


こぼれ種からのC株
イメージ 6
こっちも元気なくて下側の葉っぱが黄色くなってたりしていたけど

イメージ 14
追肥が効いたのか少し勢いが出てきた
けど写真で見比べるとわかんないなw
C株もA株同様に第1花房の上で摘芯してある

C株第1花房
イメージ 15
A株よりは元気ある

うどんこ病?
イメージ 12
イメージ 11
B株の下側の葉っぱが白くなっていたので

イメージ 13
取り除いた


スイートバジル
イメージ 16
株自体が枯れるのは防げたみたいだけど

イメージ 17
ダメージを受けた葉っぱは元には戻らないみたいで
枯れてしまうのも出てきた

イメージ 18
花も咲いてきたのでこのままにして
種を収穫しようと思う
スイートバジル育てるのは4か5回目なんだけど
この株は今までの中で香りが一番いい気がするんだよねえ
次世代に期待


土の熱消毒
イメージ 21
熱消毒はもうできただろうってことで
土を乾燥させることにした
ムカデとかヤスデが蒸し焼きになったせいか臭いので
その臭いが少しでも軽減できたらなあと

イメージ 22
かぶせているシートの前後に隙間を開けた

イメージ 23
熱を全体に通すにはある程度水分があったほうがいいはず

イメージ 24
二日目でもだいぶ乾燥してきた
もう十分な感じなのであとはプランターに土を戻すだけなんだけど
暑いんだよなあ
7月入ってからの平均気温が
26,27,28,28,26

イメージ 25
7月入ってからの最高気温もここ4年間で一番高い
「土を熱消毒していたと思ったら
いつの間にか自分が熱消毒されていた」
ってことになりかねない


クモの巣
イメージ 26
比較的綺麗に撮れていた
引っかかるとヽ(`Д´)ノウワァァァン!!ってなるけど
見る分には上手だなあと感心する


前回
復活のスイートバジル、トマトに追肥 ( ガーデニング ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14258539.html


ベランダ菜園、トマト(レッドオーレ)今季初収穫、土の熱消毒続き、イチゴのランナー

$
0
0

追肥、追土?
肥料不足な感じのA,B株のプランターに
イメージ 2
草木灰とようりんと化成肥料

イメージ 1
黒マルチを剥がたところに

イメージ 3
草木灰

イメージ 4
化成肥料(白い粒々)とようりん(黒い粒々)

イメージ 5
その上に土を追加

イメージ 6
土は以前熱消毒しておいたもの

イメージ 7
初収穫は2,3日後かなという状態で
夜から雨の予報

気象庁 Japan Meteorological Agency
http://www.jma.go.jp/jma/index.html
より引用
イメージ 8
今日のお昼すぎまでに71ミリ降った
その結果

イメージ 9
ん?割れていない?
反対側からも確認

イメージ 10
割れていた!
やっぱり割れるのかー
ってことで収穫することに
本当はあと1,2日置きたかった

積算温度
イメージ 16
今日で900度弱といったところ
やっぱりもう少し置いておきたかった
写真で見ると赤く見えるけどレッドオーレはその名の通り
もっと真っ赤になる

イメージ 11
こう掴んで
人差し指のほうを支点にして

人差し指
   ┓←この角を切り離す
🍅
親指

イメージ 12
角を真っ直ぐにするように回す感じ

イメージ 13
外れる
無造作に取るとヘタが外れちゃうんだよねえ
どうせ食べるときは捨てるんだからいいんだけど
写真撮るときはヘタがあったほうがトマトらしいからね

イメージ 14
高さ?は4センチ強

イメージ 15
直径は5センチ弱
去年は最大でも4センチ位だったから今までで一番大きい

開花から39日目で初収穫?と芯止まり、種まきから86日目、トマト(レッドオーレ)と彩雲 ( ガーデニング ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/13335450.html
去年の初収穫の様子
去年はここから更に酷い割れ方になって
まともな収穫ができたのは秋になってからだった

イメージ 17
今年はどうなるかなあ

イメージ 18
薄い、イマイチ
なぜか粉っぽい感じがした

A株
イメージ 22
追肥前

イメージ 21
追肥2日後
2日しか経っていないけど少し状態が良くなった気がする
上の方の葉っぱの枝が / から / になっている

株元のスイートバジル
イメージ 20
追肥前

イメージ 19
追肥後
しばらく変化なかったけど大きくなっている

こぼれ種からのC株
イメージ 23
イメージ 24
こっちは一昨日には追肥していないけど悪くなさそう


土の熱消毒
イメージ 25
追肥するときに土を使って右上のプランターに空きができたので
熱消毒しておいた土を戻すことにした、暑い

イメージ 26
湿っていた時は虫の死骸の臭がしていたけど
乾燥させたら臭わなくなった
枯れ葉は砕いて土に混ぜて根だけ取り除いた、暑い

イメージ 27
入りきらなかった土はこのプランターに入れて

イメージ 28
伸びてきていたイチゴのランナーから苗を取ることにした
苺の花が出てくる方向はランナーの進行方向とほぼ同じ
花はプランターの外側に向かって出て欲しい
ってことは水色枠の株の花は希望とは反対側になってしまうけど
位置的にできないから妥協

イメージ 31
日が当たるとあっという間に乾燥してしまうから
日陰にしたい、黒マルチをうまく使いたい

次の消毒
イメージ 29
左から2番めのいちごを処分して土を熱消毒
このプランターから出てきた虫は
ムカデx1、ヤスデx10、アリが無数だった
去年まではヤスデはいなかったんだよねえ
かわりにカナブン(コガネムシ)の幼虫が10匹とかだった

イメージ 30
この日は曇っていて作業にはベストな天候だったから実行したけど
それでも暑かった、晴れの日では無理だなあ


スイートバジル
イメージ 32
花が咲いて葉っぱが固くなってきた

イメージ 33
この調子なら種は収穫できそう


前回
ベランダ菜園、トマトが赤くなってきた、7月に入ってから暑い ( ガーデニング ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14270787.html#14270787


トマト(レッドオーレ)追肥後の変化、C株不調、成長点付近の葉っぱが葉脈以外の部分が黄色く周縁部が赤くなる

$
0
0

トマト(レッドオーレ)A,B株
イメージ 1
5日前

イメージ 2
今日2016年7月15日
前回の追肥が効いたみたいで株の上半分が伸びて葉っぱも大きくなった

B株第1花房の変化と収穫
イメージ 5
前回の初収穫では割れてしまったけど
今回のは4つとも無事に収穫できた

イメージ 6
イメージ 7
ミニトマトとレッドオーレの大きさ比較

イメージ 8
十分赤くなっていると思うんだけど
味はイマイチなんだよねえ、まずくはないけど
味が薄くて物足りない感じ
相変わらず皮が硬い
でも去年の収穫はじめに比べればかなりマシだし
これから美味しいのが採れるようになるのかも?

去年
うーん、去年のと見比べるの面白いなあ

今年
第2花房
イメージ 9
第1花房に比べると少し小さめで
直径は4~4.5センチくらいかな

第3花房
イメージ 10
肥料不足になってその間に開花したものは結実しなかったので
5個しかついていない

第4花房
イメージ 11
蕾がついた頃に肥料不足だったかな
追肥後に大きくなってきた
第4花房の上で摘芯したので第5花房はない

イメージ 12
追肥後に側枝も伸びてきたけど2本も要らないかなあ

A株
イメージ 13
こっちも摘芯したけど脇芽が2本伸びている
花房は1個だけなのでこちらは側枝を2本とも伸ばしてみるかなあ
それにしても側枝2は主枝と見分けがつかないけど
確か主枝は摘芯したんだよなあ

追肥前と追肥後のA株
イメージ 17
なんか元気が無いなあって思っていた頃
葉っぱが小さいままでスカスカ

イメージ 14
約1週間たってもスカスカ

イメージ 15
追肥

イメージ 16
追肥5日後
葉っぱがわさわさになってきた

横から
イメージ 18
追肥6日前から直前までの5日間と
直前から追肥4日後の5日間
同じ5日間でも成長度合いが全然違う
よっぽど肥料不足だったんだなあ
追肥はしていたんだけど足りなかったみたいね


挿し芽トマトとスイートバジル
イメージ 3
5日前

イメージ 4
今日
だいぶ伸びて同じ距離での撮影だと収まらなくなった


こぼれ種からのC株
イメージ 19
離れてみると悪くなさそうなんだけど
成長点付近の葉っぱを見ると

イメージ 20
イメージ 22
葉脈以外の部分が黄色くなって周縁部は赤っぽくなって
形も内側に縮れて小さい
この症状は去年のA,B株と同じ
こうなると成長が遅くなる

イメージ 21
伸びてきた脇芽も同様
この症状が出る前の葉っぱには影響ないけど
これから出てくる葉っぱは全部こんな状態になる

イメージ 23
これはまともなA株の成長点付近
全体が緑だし縮れていない

肥料不足の時のA株の成長点付近
イメージ 24
肥料不足でも成長点付近の葉っぱは黄色くはならない
色だと黒っぽくなって
成長点付近で開花する

C株
イメージ 25
比べると見た目が全然違う


去年の様子
トマト(レッドオーレ)種まきから98日目、雨降って実割れる、A株不調 ( ガーデニング ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/13371376.html?type=folderlist
去年はA,B,C株の内A,Bがこうなった
それでも枯れてしまうとか実がつかなくて収穫が無くなるとかは
なかったんだけど味が悪くなる感じだったかなあ
症状が出なかったC株はA,B株より美味しいものが採れた

一昨年のトマト黄化葉巻病
月間改め季刊放置栽培冬号トマト編 ( ガーデニング ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/12404037.html
これはトマト黄化葉巻病だと断定できる症状だと思う
去年や今年のは症状の出方が弱いトマト黄化葉巻病
って感じなんだよねえ



病気とは無縁?のスイートバジル
イメージ 26
いっぱい花が咲いてきた
こんなにたくさん種は要らないから
少し摘花したほうがいいかなあ



前回記事
ベランダ菜園、トマト(レッドオーレ)今季初収穫、土の熱消毒続き、イチゴのランナー ( ガーデニング ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14277279.html






エクセルVBAでライフゲームその2

$
0
0

前回
エクセル方眼紙とVBAでライフゲーム ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14597959.html

のつづき


マップの上下左右を繋げたので
マップ端でグライダーも消えることなく
反対側から出てくるようになった


イメージ 1
全体

初期配置ボタン
イメージ 2
初期配置割合によってmapに生存セルを配置する
ランダムに配置するのでボタンを押すたびに変化する

開始ボタン
イメージ 14
指定したターン数まで世代を自動ですすめる

クリア/中止
イメージ 3
map中の生存セルを消去(塗りつぶしなしに)する
開始ボタンで進めている途中でも消去する
生存セルが0になると止まるようにしてあるので
中止したいときにも使える

イメージ 4
前回と同じボタン

map範囲変更
イメージ 5
ライフゲームに使うセル範囲を変更する
↑のようにG8:P16を選択状態にしてからボタンを押すと

イメージ 6
変更完了
map範囲は赤枠がつく

設定
イメージ 7
薄いオレンジのセルはリストから値を変更可能
ターン間隔はゲームスピードなんだけど
パソコンの性能やmap範囲の大きさによっては
指定より遅くなる
map範囲が20x20セルくらいだと最速に指定しても
0.1秒と一緒くらいかなあ


ライフゲームのルール変更
イメージ 8
この状態がライフゲームの基本ルールと同じ



イメージ 9
ターン数100にして開始

イメージ 10
100ターン終了後の状態
セルの色は誕生直後は黒で生存し続けるとジョジョに赤くなるようにしてある
5世代続いたら真っ赤になる
下にあるグラフは生存率の変化で、終了後に表示(更新)される

設定を変えて遊んでみる
イメージ 11
生存条件を生き残りやすく1~4に変更すると
迷路状になって固定される

イメージ 12
全部1
新陳代謝激しいけど意外に5世代続くセルもある


イメージ 13
8,8,0
これ形も面白いし、変化もおもしろい


以前からだけどボタンや説明画像に使ったかっこいいフォントは
フロップデザインフォント
フリーフォント - フロップデザインフォント無料ダウンロード日本語ウェブフォント
https://www.flopdesign.com/freefont/flopdesignfont.html
素晴らしい


今回のエクセルファイル
今回のコードとか
エクセルVBAでライフゲームその2のコードと名前の付いたセル範囲の一覧作成マクロ ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14608298.html


エクセルVBAでライフゲームその2のコードと名前の付いたセル範囲の一覧作成マクロ

$
0
0


前回の記事
エクセルVBAでライフゲームその2 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14606097.html

の補足
上下左右ループ

前々回
前々回ではループさせていなかったので端に行くと消えたり詰まったりしていた

前回
前回でループするようにした




赤枠が全体マップ
黒枠が11番のセルの周囲を探索するときの範囲
セルa,b,cはマップ外なので探査しても無意味になる
左右をつなげるには、それぞれ10,15,20が入るようになっていればいい

イメージ 5
こうなっていればいいので

イメージ 6
右側を左側の外にコピペで
左側が右側に繋がったことになる

イメージ 7
上下左右コピペ
後の四隅は対角

イメージ 8
これで探査用のシートはOK


イメージ 2
例えば表示用がこんな状態のとき探査用のシートは

イメージ 1
右のようになっているので
次の世代には

イメージ 3
1番に誕生して5番が生存維持になる
ループなしだと全滅


こんな感じでループするようにしたんだけど
1ターンに9回もコピペを繰り返しているのが遅くなっている原因かなあ
探査用のシートを使わないで配列変数を使えば少し早くなるはずなんだけど
ほとんど書き直すことになっちゃうなあ


コード全部

'次の世代へ更新
Function NextGeneration() As Long
    Application.ScreenUpdating = False
    Call CopyAtoB    '判定用シート(lifegameB)にコピー
    Dim mA As Range
    Set mA = Range("mapA")
    Dim cc As Long, rc As Long, lifeCount As Long
    rc = mA.Rows.Count
    cc = mA.Columns.Count
    Dim lifeLower As Long, lifeUpper As Long, lifeBirth As Long
    lifeLower = Range("下限").Value
    lifeUpper = Range("上限").Value
    lifeBirth = Range("誕生").Value

    Dim ci As Long 'colorIndex
    Dim sr As Long 'searchResult
    
'    Dim ti As Single, tc As Single '処理時間計測用
'    ti = Timer
    
    For x = 1 To rc
        For y = 1 To cc
            Dim rA As Range, rB As Range
            Set rA = Range("mapA").Cells(x, y)
            Set rB = Range("mapB").Cells(x, y)
            ci = rB.Interior.ColorIndex
            sr = SearchCell(rB) '周囲のセルを探査
            
'            If ci = xlColorIndexNone And sr = lifeBirth Then
'                '周囲の生存セル数が3なら誕生
'                'ra.Interior.ColorIndex = 1
'                Call NuriBlack(ra)
'                lifeCount = lifeCount + 1
'            ElseIf ci = 1 And (sr >= lifeLower And sr <= lifeUpper) Then
'                '周囲の生存セル数が2か3なら生存
'                'ra.Interior.ColorIndex = 1
'                Call NuriBlack(ra)
'                lifeCount = lifeCount + 1
'            Else
'                '上記以外なら消滅
'                ra.Interior.ColorIndex = xlColorIndexNone
'            End If

            '↑0.13秒、↓0.10秒        
            
            If ci = xlColorIndexNone Then
            '塗りつぶしなしのセルの場合
                If sr = lifeBirth Then
                    lifeCount = lifeCount + 1
                    rA.Interior.ColorIndex = 1 '黒塗り
'                    rA.Interior.Color = RGB(255, 0, 0) '赤塗
                    'Call Nuri2(ra, rb)
                End If
            Else
            '色付きセルの場合
                If (sr >= lifeLower And sr <= lifeUpper) Then
                    lifeCount = lifeCount + 1
                    Call Nuri2(rA, rB) '塗る
'                    rA.Interior.ColorIndex = 1 '黒塗り
'                    rA.Interior.Color = RGB(255, 0, 0)
                Else
                    rA.Interior.ColorIndex = xlColorIndexNone '消滅
                    rB.Value = 0
                End If
            End If
            
            
        Next y
    Next
    
'    tc = Timer - ti
'    Debug.Print (tc)
    
    NextGeneration = lifeCount
    
    Application.ScreenUpdating = True
End Function

Sub NuriBlack(r As Range)
   r.Interior.ColorIndex = 1
End Sub

Sub Nuri2(rA As Range, rB As Range)
    rB.Value = rB.Value + 64
    If rB.Value > 255 Then rB.Value = 255
    rA.Interior.Color = rB.Value
End Sub

'周りの8セルを探査、色付きのセルの個数を返す
Function SearchCell(r As Range) As Long
    Dim c As Long
    For y = -1 To 1
        For x = -1 To 1
            If r.Offset(x, y).Interior.ColorIndex <> xlColorIndexNone Then
                If Not (x = 0 And y = 0) Then '自身はカウントしない
                    c = c + 1
                End If
            End If
        Next
    Next
    SearchCell = c
End Function


Sub initial初期配置()
    Dim r As Range
    Set r = Range("mapA")
    r.Interior.ColorIndex = xlColorIndexNone
    Dim rr As Range
    For Each rr In r
        Randomize
        If Rnd < Range("liferacio").Value Then '0.2なら約2割のセルを黒で塗る
            rr.Interior.ColorIndex = 1
        End If
    Next
    Range("lifecount").Value = GetLifeCount生存数カウント
    Range("mapB").ClearContents 'mapBの数値クリア
End Sub

'生存数カウント
Function GetLifeCount生存数カウント() As Long
    Dim r As Range
    Dim life As Long
    For Each r In Range("mapA")
        If r.Interior.ColorIndex <> xlColorIndexNone Then
            life = life + 1
        End If
    Next
    GetLifeCount生存数カウント = life
End Function

'全セル塗りつぶしなし
Sub ClearColor()
    Worksheets("lifegameA").Activate
    Range("mapA").Interior.ColorIndex = xlColorIndexNone
    Range("mapB").ClearContents
End Sub


'mapAからmapBへコピペ、上下左右ループ対応
Sub CopyAtoB()
    '判定用シート(lifegameB)に書式だけコピー
    'Range("mapA").Copy Range("mapB")
    Range("mapA").Copy
    Range("mapB").PasteSpecial xlPasteFormats
    
    Dim r As Range, rr As Range
    Set r = Range("mapB")
    Dim rc As Long, cc As Long
    rc = r.Rows.Count
    cc = r.Columns.Count
    
'4辺を反対側の外側にコピペ
    '1行目を最終行+1行目にコピペ
    r.Rows(1).Copy r.Rows(rc + 1)
    '最終行を0行目にコピペ
    r.Rows(rc).Copy r.Rows(0)
    '1列目を最終列+1列目にコピペ
    r.Columns(1).Copy r.Columns(cc + 1)
    '最終列を0列目にコピペ
    r.Columns(cc).Copy r.Columns(0)
    
    '四隅を対角線反対側の外にコピペ
    r.Cells(1, 1).Copy r.Cells(rc + 1, cc + 1) '左上を右下に
    Set rr = r.Cells(1, 1).Offset(-1, -1)
    r.Cells(rc, cc).Copy rr         '右下を左上に
    Set rr = r.Cells(rc, 1).Offset(1, -1)
    r.Cells(1, cc).Copy rr          '右上を左下に
    Set rr = r.Cells(1, cc).Offset(-1, 1)
    r.Cells(rc, 1).Copy rr          '左下を右上に
End Sub

'マップの範囲変更、選択範囲をライフゲームの範囲にする
Sub ChangeMapRangeマップの範囲変更()
    If TypeName(Selection) <> "Range" Then Exit Sub
    If Selection.Areas.Count > 1 Then
        MsgBox "複数の選択範囲は選べない"
        Exit Sub
    End If
        
    If MsgBox("選択範囲をライフゲームの範囲に変更します", vbYesNo) = vbYes Then
        Dim rA As Range, rB As Range
        
        'mapA
        Set rA = Range("mapA")
        rA.ClearFormats '古い範囲の書式をクリア
        '範囲の変更と新しい範囲に枠線
        Set rA = Selection
        rA.Name = "mapA"
        rA.Borders.Color = RGB(200, 200, 200) '灰色罫線
        rA.BorderAround , xlThin, 3 '赤枠
        Worksheets("lifegameA").Calculate
        
        'mapB
        Set rB = Range("mapB")
        Set rB = rB.Offset(-1, -1)
        Set rB = rB.Resize(rB.Rows.Count + 2, rB.Columns.Count + 2)
        rB.Clear
        
        Worksheets("lifegameB").Range(rA.Address).Name = "mapB"
        Set rB = Range("mapB")
        rB.BorderAround , xlThin
        
    End If
    
End Sub

'指定回数NextGeneration関数をループ
Sub AutoNext()
    Dim t As Long
    t = Range("ターン数").Value
    Dim lifeArray() As Long 'ターン毎の生存数カウント
    ReDim lifeArray(t)
    lifeArray(0) = GetLifeCount生存数カウント
    
    Dim ti As String
    ti = Range("ターン間隔").Value
    Dim lifeC As Long
    For i = 0 To t - 1
        lifeC = NextGeneration      '次世代へ進める
        Range("nowtrun").Value = i + 1 '現在ターン表示更新
        Range("lifecount").Value = lifeC    '生存数表示更新
        lifeArray(i + 1) = lifeC    '生存数を配列に
        If lifeC = 0 Then Exit For  '生存数0(全滅)ならループを抜ける
                
        '表示更新間隔
        'Application.Wait (Now + TimeValue("0:0:1")) '1秒単位
        If ti = "最速" Then
            Application.Wait [now() + "0:00:00.01"] 'ミリ秒単位
        ElseIf ti = "0.1秒" Then
            Application.Wait [now() + "0:00:00.1"] 'ミリ秒単位
        ElseIf ti = "0.5秒" Then
            Application.Wait [now() + "0:00:00.5"]
        ElseIf ti = "1秒" Then
            Application.Wait [now() + "0:00:01"]
        Else
            Application.Wait [now() + "0:00:00.5"]
        End If
        
        DoEvents 'これがないと画面の更新がされない
    Next
    'グラフの更新
    Call ChangeChart(lifeArray)
End Sub


'2 次元配列の行列を入れ替える: やむえむのExcel VBAメモ

'グラフの更新、すべてのターン終了後にまとめて更新
Sub ChangeChart(Lifes() As Long)
    Range("lifelog").Offset(1, 0).ClearContents
    
    Dim lc As Long
    lc = UBound(Lifes)
    
    '密度density、配列に入れる
    Dim cc As Long
    cc = Range("mapA").Cells.Count
    Dim Density() As Single, Density2 As Variant
    ReDim Density(lc)
    For j = 0 To UBound(Density)
        Density(j) = Lifes(j) / cc
    Next
    
    '配列をそのまま貼り付けると横になる
    '縦に貼り付けたいのでワークシート関数のTransposeで縦横入れ替える
    Dim Lifes2 As Variant
    Lifes2 = Application.WorksheetFunction.Transpose(Lifes)
    
    '生存数をシートに貼付け
    Dim r As Range
    Set r = Range("lifelog").Resize(lc + 1, 1).Offset(1, 1)
    r.Value = Lifes2
        
    '密度も縦横を入れ替えてから貼り付け
    Dim rr As Range
    Set rr = r.Offset(0, -1)
    Density2 = Application.WorksheetFunction.Transpose(Density)
    rr.Value = Density2
    
    'シートを再計算してグラフの表示を更新
    ActiveSheet.Calculate
End Sub


ボタンとマクロの対応
イメージ 9



名前を付けたセル範囲
イメージ 4
こういう一覧を作るマクロが
'名前の付いたセル範囲の一覧作成
'アクティブセルを基準に書き込む
Sub rangeName()
    Dim n As Names
    Set n = ActiveWorkbook.Names
    Dim v() As Variant
    ReDim v(n.Count, 1)
    v(0, 1) = "参照範囲"
    v(0, 0) = "名前"
    Dim str As String
    For i = 1 To n.Count
        str = n.Item(i).Value
        str = Right(str, Len(str) - 1)
        v(i, 1) = str ' n.Item(i).Value
        v(i, 0) = n.Item(i).Name
    Next
    
    ActiveCell.Resize(UBound(v) + 1, 2).Select
    If MsgBox("選択範囲に書き込んでもいい?", vbYesNo) = vbNo Then Exit Sub
    Selection.Value = v
End Sub




続き
エクセルVBAでライフゲームその3 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14611521.html






エクセルVBAでライフゲームその3

$
0
0

別シートで行っていたセルの探査を配列を使うようにしたら2倍くらい速くなった

イメージ 1
1世代更新にかかった時間
20x20だと0.22秒から0.11秒
40x20だと0.36秒から0.14秒
セル数が増えると余計に差がでてくる

動かしているところ
速くなっていい気分!

その後何色かを選べるようにしたら
イメージ 7
0.11秒だったのが0.15秒まで遅くなったw
でも前回より速いからね

前回との変更点
処理速度向上
生存率のグラフをリアルタイムで変更するようにした
誕生ルールを2つ指定できるようにした
mapの上下左右ループの有無を指定できるようにした
生存し続けたセルの色変化で選べる色を赤、緑、青、水色から選べるようにした
それぞれの色で変化なしもできるようにした
クリアと中止を分けて、中止ボタンはクリアしないで停止するようにした
ゲーム実行中は中止以外のボタンを無効にするようにした



セルの状態を配列に入れる処理の流れ
2次元配列を2つ使う、それぞれA, Bとしたら
  1. Aにmapのすべてのセルの状態(色の有無)を入れる
  2. BにはAを使ってセルの探査結果を入れる

4x2のmap(赤枠)で(0, 0)だけ色付きのセル
イメージ 8
この状態の時に

'現在のmapの状態を返す
'生存セルならTrue、それ以外ならFalseを格納した2次元配列を返す
Function GetState() As Boolean()
    Dim map As Range
    Set map = Range("map")
    '2次元配列を作成、これにセルの状態を入れる
    Dim rc As Long, cc As Long
    rc = map.Rows.Count - 1
    cc = map.Columns.Count - 1
    Dim v() As Boolean
    ReDim v(rc, cc)
    
    Dim x As Long, y As Long
    For x = 0 To rc
        For y = 0 To cc
            'false 0, true -1,塗りつぶしなしなら0、色付きなら-1
            v(x, y) = map.Cells(x + 1, y + 1).Interior.ColorIndex <> xlColorIndexNone
        Next
    Next
    GetState = v
End Function
これが1番の部分になる
2次元配列Aを作ってmapのすべてのセルの状態(色の有無)を入れる
これを実行して返ってきた中身は↓

イメージ 5
2次元配列はセルの並びと同じ感じでx, yの座標みたいになるので
同じように探査できる
色付きならTrue、なしならFalseをいれるようにしてあるので
(0, 0)の要素だけTrueが入っている
で、これを使って

2番のBにはAを使ってセルの探査結果を入れる
このコードが↓

'map全体を探査
'色付きの周囲セルの個数を格納した2次元配列を返す
'           ループなし
Function GetNextLifePointNoLoop() As Long()
    Dim st() As Boolean
    st = GetState '現在のmapの状態を取得
    Dim rc As Long, cc As Long
    rc = UBound(st, 1) 'RowsCount
    cc = UBound(st, 2) 'ColumnCount
    Dim x As Long, y As Long, LifeP As Long
    Dim xx As Long, yy As Long
    Dim v() As Long '配列
    ReDim v(UBound(st, 1), UBound(st, 2))
    
    For x = 0 To rc
        For y = 0 To cc
            LifeP = 0
            
            For i = -1 To 1
                For j = -1 To 1
                    
                    'Offset位置の調整、配列の外側に出たらなにもしない
                    xx = x + i
                    yy = y + j
                    If Not (i = 0 And j = 0) Then
                        If Not (xx < 0 Or xx > rc Or yy < 0 Or yy > cc) Then
                            If st(xx, yy) = True Then
                                LifeP = LifeP + 1 '色付きならカウントアップ
                            End If
                        End If
                    End If
                Next j
            Next i
            'カウントを記入
            v(x, y) = LifeP
            
        Next
    Next
    GetNextLifePointNoLoop = v
End Function
配列の中で探査している
周囲8個のセルで色がついている数を配列Bに入れていく
これで返ってくる中身は
イメージ 4
こう

イメージ 2
この状態のときは

イメージ 3
こんな感じで自分の周りで色付きのセルの個数がそれぞれ入っている

後はこの数値とルールを比べて色を塗ったり消したりするだけ
基本ルールだと3個あれば誕生するので
(0, 2)と(1, 2)が3で自身は空白だからこの2つが黒になって
生存判定だと今生きているセルの判定数値は1だから消滅
なので
□□■□
こうなるはず
イメージ 6


今回のファイル:ライフゲーム3.xlsm
ヤフーボックス


前回の記事
エクセルVBAでライフゲームその2のコードと名前の付いたセル範囲の一覧作成マクロ ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14608298.html














午後のパレットその45、セルの右クリックメニューにシート一覧とウィンドウ一覧など色々追加した

$
0
0

午後のパレットに機能を追加したり修正したりした

2016/11/18
午後のパレットのマイパレットを10枚から21枚に増やした

2016/11/21
午後の縞々追加
偶数奇数行に対して背景色、文字色、罫線の色指定をするツール

2016/12/14
右クリックメニュー関連
シート一覧
ウィンドウ一覧
アドインダイアログを開くボタン追加
2016/12/15
午後のパレット終了時にクラスを入れた変数の初期化(Erase)をするようにした
Erase クラスを入れた変数
意味があるかはわからない

前回の記事は
午後のパレットその44、選択図形の枠の色を変えることができるようにしてみた ( Windows ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/13317489.html


見た目の変化
イメージ 3
パレット以外にも色々増えてきたので
リボンに表示される名前をパレットから午後ツールに変更
それに伴ってボタンの名前も幾つか変更した


午後のパレットのマイパレットを10枚から21枚に増やした
イメージ 2
びろ~ん

イメージ 1
初期設定の状態
12から21までのものを追加したくて枚数を増やした
もちろん気に入らなければ好きな色に置き換えられる


午後の縞々
イメージ 4


セルの右クリックメニューに色々追加
シート一覧ボタン
イメージ 5
シートを選択するボタンを追加する
これは以前にもマクロとして作ったのを少しいじってアドインに追加したもの
エクセル2007、右クリックメニューにシート一覧ボタンを作成するマクロ修正版 ( Windows ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/12322573.html
MHP3はジンオウガ討伐で止まったままだなあ、2年前かあ


ウィンドウ一覧ボタン
イメージ 6
開いているウィンドウの一覧ボタンを追加
ボタンクリックでそのウィンドウを表示(Activeに)する
で、
これとほとんど同じ機能はエクセルに最初からあることを知ったのは
ほぼ作り終わってテストしている時
イメージ 7
表示タブのウィンドウの切り替えとほとんど同じ機能

違い
イメージ 8
ウィンドウを10枚以上開いた状態だと一覧に表示されないので
ウィンドウの選択画面から選ぶことになる
クリック数は5か6回

対して右クリックメニューからだと
イメージ 9
クリック数は2か3回!
でもエクセルのウィンドウを10枚以上開くことは…あんまりないよね、うん


アドインダイアログを開くだけのボタン
イメージ 10
エクセル2007だと4回もクリックしないとたどり着けないのがめんどくさくて付けた

イメージ 11
ででーん



午後ツールのダウンロード先
ヤフーボックス
午後のパレット_20161212.xlam
https://box.yahoo.co.jp/guest/viewer?sid=box-l-3rjuj7hqmqr7b3al3lvxcim3ku-1001&uniqid=4e0033bf-d328-453e-a84a-28fd67a81d10&viewtype=detail
エクセル2007で作っているので古いエクセルでは動かない
2010,2013,2016は動くかどうかわからない

アドインの導入方法はググったほうがいいけど昔書いた記事
エクセル2007アドイン、セルの塗りつぶしとフォントのパレット作ってみた ( Windows ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/12379483.html

使い方
┗午後のパレット使い - リスト表示 - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/folder/548680.html?m=l


それぞれの細かい動作はまた今度
午後の縞々の説明記事
午後ツール(午後のパレット)その46、午後の縞々 ( Windows ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14621141.html

右クリックメニュー
午後ツール(午後のパレット)その48、セルの右クリックメニューにシート一覧ボタンと ウィンドウ切り替えボタンの使い方 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14627629.html




午後ツール(午後のパレット)その46、午後の縞々

$
0
0

エクセルのアドイン午後ツールの1つ
午後の縞々の説明

午後ツールは前回の記事
午後のパレットその45、セルの右クリックメニューにシート一覧とウィンドウ一覧など色々追加した ( Windows ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14619620.html

イメージ 10
午後ツールタブの縞々ってあるボタンをクリックすると表示される

イメージ 1
見た目はこんな感じ

使用例
動かしているところ

目的とか特徴
セルの塗りつぶしで偶数行と奇数行交互にしたい
結果予想の見本を見ながら色をRGBとHSLどちらでも設定できる
文字色と罫線の色、罫線の有無も指定できる
バグあり



塗りタブ、セルの塗りつぶしの設定をする
イメージ 2
🔘奇数行、🔘偶数行で設定する行を切り替える
塗りつぶしなしにしたいときは奇無色、偶無色にそれぞれ✅を入れる
"逆行へコピー"を押すと設定中のとは逆の行へ色をコピーする
"入れ替え"を押すと奇数、偶数の色を入れ替える
"選択範囲に適用"を押すと選択しているセル範囲に設定した色が適用される

"セルから取り込み"
選択セル範囲の左上とその下のセルの色を午後の縞々に取り込むので
選択範囲がA1:A4なら、A1(左上)とA2(その下)の色を取り込むので↓こうなる
イメージ 4

選択範囲がB3:D5なら
B3(左上)とB4(その下)で↓こうなる
イメージ 3

選択セルが1つか1行のときは奇数偶数どちらの色も同じ扱いにしたので
↓こうなる
イメージ 5
って、偶数行の指定の色を更新するの忘れてたみたいで前回の色が残っているな…



文字タブ、セルの文字色の設定
イメージ 6
文字色指定有効にチェックを入れないと適用ボタンを押しても
文字色は変化しないので背景色と文字色の組み合わせの確認にも使える



罫線タブ、罫線の色指定
イメージ 7
縦横罫線を指定したときの見本は正確には表示されなくて
どちらか一方だけにチェックを入れた場合でも縦横両方が表示される
でも見本だけなので選択範囲に適用ボタン押したときの結果はチェック通りになる
横罫線だけにチェックを入れた場合は横だけ引かれる

コピー
イメージ 8
塗りタブの色をコピーする
塗りタブで奇数行の色を設定中ならその色が罫線にコピーされる

その他設定タブ
イメージ 9
何も無いです
このアドインを作っていたのは涼しくなった10月下旬くらいだったかなあ
その時は何かあったか何かをつけようと思っていたんだろうけどもう忘れた
…思い出した!しましまの設定を保存する機能だ


次の記事、しましまの設定を保存する機能ついた!
午後ツール(午後のパレット)その47、午後の縞々新機能といろいろ修正 ( Windows ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14622904.html





午後ツール(午後のパレット)その47、午後のしましま(縞々)新機能といろいろ修正

$
0
0

2016/12/17
午後の縞々、名前を午後のしましまに変更
しましまの設定を保存する機能を追加
セルから取り込み時に偶数行のラジオボタンの隣の色見本の色の更新がされていないのを修正
全般
ウィンドウ(ブック)が1つも開かれていないときは起動できないようにした
午後のパレット
シートが作業グループのときに塗り↔文字↔枠の切り替えボタンを押すとエラーになっていたのを修正
ウィンドウ(ブック)が1つも開かれていないときにマイパレットの変更やその他の操作をするとエラーになっていたのを修正



縞々だと禍々しいと紛らわしいのでしましまに変更
イメージ 1

マイしましま
ボタンにしましま状態を登録しておいて
ボタンを押すと選択セルに適用される
ボタン右クリックから別のしましまを登録できるけど
次回以降午後のツールをバージョンアップさせると登録し直しになる(えー)

処理時間
イメージ 6
ステータスバーに処理時間を表示する

多く(10万以上)の行を縞々にしようとすると時間がかかるので
イメージ 7
目安を表示して確認
はいで1048576行をしましまにすると

イメージ 8
あれ?57秒、作っているときには52秒前後だったのに
古いパソコン(2009年)だと100万行しましまにするには約1分かかる
逆に列はほとんど時間がかからなくて

イメージ 9
すべての列(16384列)をしましまにするには

イメージ 10
たったの0.03秒
100万行と1.6万列じゃ列のほうが速いの当たり前?

イメージ 11
じゃあ列と同じ数の16384行で計測

イメージ 12
0.76秒
20倍も遅いのは横の縞々だから
1行ごとに色を指定するから時間がかかる
列はどこまで行っても同じ色だから一回の指定で終わる





エラーの回避とか修正とか
イメージ 2
ウィンドウ(ブック)が1つも開かれていないのに
起動できちゃうと色々面倒なので起動できないようにした
といっても
起動した状態からすべてのブックが閉じられると残ってしまう

イメージ 4
この状態からブックを閉じると

イメージ 3
残ってしまう
この状態で色々操作するとエラーになることがある


イメージ 5
これが出たら終了を押せば
アドインたちが閉じられる
理想ではすべてのブックが閉じられたらアドインたちも閉じられればいいんだけど

3. アドインの切り離し - Excel VBAによるアプリケーション開発
http://excelappwithvba.web.fc2.com/disjunction_of_code_and_data/dropping_addin.html
ここ見ても
エクセル2007では無理みたい
エクセル2010以降ならもう少しなんとかできそうな感じなんだけどねえ
空から新しいエクセル降ってこないかしら

午後のパレットのエラーの修正
イメージ 13
Sheet3からSheet5までが作業グループになっている状態
こういう状態で午後のパレットで塗り↔文字↔枠の切り替えボタンを押すと
かなりひどいエラーになっていたので

イメージ 14
操作できないようにした
複数のシートが選択されている=作業グループ
メッセージわかりにくいなw

午後ツールは作業グループには対応していないし
これからもするつもりがないのは
作業グループはめったに使わないから


午後ツールダウンロード先(ヤフーボックス)

前回の記事
午後ツール(午後のパレット)その46、午後の縞々 ( Windows ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14621141.html

次の記事
午後ツール(午後のパレット)その48、セルの右クリックメニューにシート一覧ボタンと ウィンドウ切り替えボタンの使い方 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14627629.html














午後ツール(午後のパレット)その48、セルの右クリックメニューにシート一覧ボタンと ウィンドウ切り替えボタンの使い方

$
0
0
午後のパレットその45、セルの右クリックメニューにシート一覧とウィンドウ一覧など色々追加した ( Windows ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14619620.html
↑の続き

エクセルのアドイン午後ツールのセルの右クリックメニューにシート一覧ボタンと
ウィンドウ切り替えボタンの使い方


イメージ 17




セルの右クリックメニューにウィンドウ切り替えボタンを追加する
イメージ 26
ウィンドウ切り替えボタン作成をクリックした後に
セルを右クリックしてみると…
イメージ 27
一番上に追加される

イメージ 2
Book2をクリックすると…

イメージ 3
Book2に切り替わる

遠すぎたウィンドウ切り替え
イメージ 4
ウィンドウを切り替えるのに画面の一番下まで
マウスを移動させるのがめんどくさい!
そんなときに使う


ウィンドウ切り替えボタンの削除方法1
エクセルを終了する

ウィンドウ切り替えボタンの削除方法2
イメージ 8
削除ボタンがあるのでクリックすると削除される

イメージ 9
セルを右クリックして確認




シート一覧(切り替え)ボタン作成
イメージ 10
通常はこちらの自動更新ありを使う
これをクリックすると…

イメージ 11
確認画面が出る、OKで作成される
セルを右クリックすると…

イメージ 12
ブック名+シート一覧というボタンが一番上に追加されて
マウスカーソルを置くと右側に
シートの一覧ボタンが表示されるようになる

ブックごとに別々のボタンになるので
例えばBook2のシート一覧ボタンを作るときは
Book2を表示した状態でボタン作成する
イメージ 13
Book2を開いて一覧ボタンを追加したところ
Book2のSheet2をクリックすると…

イメージ 14
シートが切り替わる

表示しているブックとは別のブックのシートに切り替える
Book2を表示している状態からBook1のSheet3を表示
イメージ 15
クリックすると…

イメージ 16
切り替わった
普通の操作だとブックを切り替える→シートを切り替える
っていう2つの操作が必要になるけどこれなら1回で済む


2016/12/19
右クリックメニューのシート一覧(自動更新なし)で閉じられたブックのシートを選択するとエラーになっていたのを修正
ダウンロード先:ヤフーボックス








ここから細かい動作や仕様など


シート一覧からブックも切り替わるのなら
ウィンドウ切り替えボタンは
必要ない
そんなふうに考えていた時期が僕にもありました


ウィンドウ切り替えじゃなくてブック切り替えじゃないの?
イメージ 5
例えばBook2で新しいウィンドウを開くを実行してから
その下の整列で

イメージ 6
作業中のブックのウィンドウを整列にチェック入れて

イメージ 18
こんなふうに別々のシートを参照することがよくある
この同じブックのウィンドウが複数ある状態だと
それぞれのウィンドウに、ブック名の後に":"と連番がついた名前がつく
Book2:1
Book2:2

このウィンドウ名を指定する必要があるんだけど
シート一覧ボタンはブック名でしか指定できないので困った…
ということでウィンドウ切り替えボタンは必要でした

ウィンドウ切り替えボタンなら
イメージ 7
こんなふうにウィンドウ名で指定できる

同ブックで複数ウィンドウを開いているときは
たいてい表示しているシートはウィンドウごとに固定だから
ウィンドウごとのシート切り替えはなくてもいいかなと

複数ウィンドウが開かれているブックのシートを別のブックから指定した場合は
1番目の(":1"が付いている)ウィンドウがアクティブウィンドウになって
その中のシートが表示されるようにした、仕様
イメージ 1
Book2が複数ウィンドウでそれぞれのウィンドウ名が
Book2:1
Book2:2
Book1の右クリックメニューからBook2のSheet1を選択すると
Book2:1がアクティブウィンドウになってその中のSheet1が表示される

複数ウィンドウでも同じブックの場合は1番目のウィンドウに切り替わること無く
シートだけが切り替わる
イメージ 19
Book2:2からBook2のSheet1を指定すると
Book2:2のSheet1が表示される



シートボタン一覧の自動更新ありとなしの違い
なしだと
イメージ 20
この状態からSheet1を削除しても

イメージ 21
シート一覧ボタンは削除されない
他にも追加や名前の変更などしても変化しない
これが自動更新なし

ここで存在しないBook1のSheet1をクリックすると
イメージ 22
これが出るようにしてある
作り直すってのは
イメージ 23
またこのボタンを押してねってこと

こんなめんどくさい自動更新なしバージョンがあるのは
ありだとシートが多いと表示に時間がかかるから
イメージ 24
シート数100枚だと0.5秒くらいかかる
うーん、こんなにシートが増えることないし
リストがこんなに伸びると逆に選ぶのもめんどくさいから
自動更新なしバージョンは要らない気がしてきた


シート一覧ボタンの削除方法1
エクセルを終了する

シート一覧ボタンの削除方法2
ないです
というか普通の方法がなくて
削除したい一覧のブックを閉じてからになってしまう
例えばBook1シート一覧ボタンを削除したい場合は
Book1を閉じてから一覧ボタンのどれかをクリックするとでてくる
イメージ 25
この画面ではいをクリックすると削除される


つづき
午後ツール(午後のパレット)その49、エクエルのカラーピッカー(アドイン)午後は何色を作ってみた ( Windows ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14630169.html




午後ツール(午後のパレット)その49、エクエルのカラーピッカー(アドイン)午後は何色を作ってみた

$
0
0

エクセルアドイン、午後ツール(午後のパレット)更新
2016/12/20
  • 右クリックメニューにウィンドウ切り替えボタンがあるときはシート一覧をその下に追加するようにした
  • アドイン、カラーピッカーの午後は何色を追加


右クリックメニューへシート一覧の追加場所変更
イメージ 7
この状態から今表示しているブック(午後のパレット_20161220)の
シート一覧を追加してみる

イメージ 8
これをクリックして確認してみる

イメージ 9
以前は一番上に追加していたけどウィンドウ切り替えボタンがあるときは
その下に追加するようにした







午後は何色
イメージ 1

選択した物の塗りつぶしの色(Fill)と文字色(Font)、枠色(Border)を表示する
対象にできるものは
  • Range、セル
  • Shape、図形
  • ShapeRange、図形
  • ChartArea、グラフ全体
  • PlotArea、グラフ内部
  • Series、グラフデータ系列(グラフ線とかの要素)
  • Axis、グラフ軸
  • Legend、グラフ凡例

色の表示形式は
  • RGB(255, 255 ,255)
  • HSL(360, 255, 255)
  • Long(10進数)
  • #(HEX、16進数)
  • NTSC(輝度)
  • HDTV(輝度、ガンマ値2.2)


イメージ 2
起動するアイコンの場所はここ


イメージ 3
よく使うものの色はだいたい取得できるけど


イメージ 4
スタイルのテーブルとして書式設定したセルの色は…


イメージ 5
取得できない
テーブルの書式は特別みたいねえ
他にも取得できない時があると思う
それでも…


イメージ 6
コピペすれば取得できる

ダウンロード先(ヤフーボックス)





同じ塗りつぶしでも対象物が変わると色のある場所が変わる
セルの塗りつぶしはInterior.Color
図形やグラフ全体はFill.Forecolor
グラフの軸や要素はFormat.Forecolor
ああでもInteriorはセルだけっぽいから、セル以外はFill.ForecolorかFormat.Forecolorのどちらかってことでいいのかなあ
あとはグラデーションの場合だとまた違った場所に変わったりだとか
エクセル2007ではグラデーションの枠の色は取得できなさそうだとか
エクセル2007は図形やグラフのマクロは記録できないから全部手作業とかで
見た目や機能が単純な割にはかなり手間がかかった

グラフの色取得は難しい
グラフの種類を変えただけで同じ要素でも塗りつぶしが枠になったり
2Dグラフで背景だったのが3Dグラフだと壁や床に変わったり
色指定が自動の場合にどこにその色があるのかわからなかったり
なのでグラフの色が自動だった場合は真っ黒や真っ白になって間違っているところもある


選択されているものの取得はとりあえず型指定した変数に入れてみて
入らなかったらそれは違う型だったんだなって言う無理矢理な方法を使っている

    On Error Resume Next
    Dim r As Range: Set r = Selection 'セル
    Dim sr As ShapeRange: Set sr = Selection.ShapeRange '図形の場合
    Dim ca As ChartArea: Set ca = Selection 'ChartAreaグラフ全体
    Dim pa As PlotArea: Set pa = Selection 'PlotArea、グラフ内部
    Dim ser As Series: Set ser = Selection 'Series、データ系列(グラフ線とかの要素)
    Dim ax As Axis: Set ax = Selection 'Axis、軸
'    Dim gl As Gridlines: Set gl = Selection 'Gridlines、目盛線
    Dim leg As Legend: Set leg = Selection 'Legend、凡例
    Dim s As Shape: Set s = Selection 'Shape、図形
    
    Select Case True
        Case Not r Is Nothing
        'セルの場合
            Me.LabelType表示用.Caption = TypeName(r)
            GetSelectionColorSet = GetCellColor(r.Cells(1))
        Case Not sr Is Nothing
        '図形
            Me.LabelType表示用.Caption = TypeName(sr)
            GetSelectionColorSet = GetShapeRangeColor(sr)
        Case Not ca Is Nothing
        Case Not pa Is Nothing
        Case Not ser Is Nothing
        Case Not ax Is Nothing
'        Case Not gl Is Nothing
        Case Not leg Is Nothing
        Case Not s Is Nothing
        Case Else
            Me.LabelType表示用.Caption = "n/a"
    End Select

    On Error GoTo 0

こんな感じだから選択対象の型が増えていくとキリがないから別の方法だなあ


前回の記事
午後ツール(午後のパレット)その48、セルの右クリックメニューにシート一覧ボタンと ウィンドウ切り替えボタンの使い方 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14627629.html


次の記事
午後ツールその50、午後のパレットその他更新 ( Windows ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14639262.htm

l

午後ツールその50、午後のパレットその他更新

$
0
0

エクセルアドインの午後ツール更新


午後のその色は
イメージ 1
2016/12/23
午後は何色?→午後のその色は
塗りと文字のグラデーションに対応、2色目まで取得できるようにした
透明度を表示するようにした
取得した色をセルに塗るボタンを付けた
コード全面書き換えでグラフの色もほぼ取得できるようになった


便利ボタン?
イメージ 2

イメージ 4

イメージ 5
2016/12/25
午後ツールに
入力規則のIME設定のボタンを追加
IMEコントロールオフを設定する
入力規則解除
入力規則確認
条件付き書式のセルを確認(選択)するボタンを追加


午後のパレット
イメージ 3
2016/12/24
午後のパレットの罫線のボタン6個追加
上下罫線
左右罫線
外枠
格子
外枠削除
内側罫線削除
終了処理時にクラスを入れた配列の初期化と削除をするようにした、必要ないかも?
起動時に表示するパレットをテーマカラーからマイパレットに変更した


ダウンロード


前回の記事
午後ツール(午後のパレット)その49、エクエルのカラーピッカー(アドイン)午後は何色を作ってみた ( Windows ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14630169.html


関連記事1
午後ツールその51、IMEオフと条件付き書式セル選択ボタンとそのマクロ ( Windows ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14640395.html





















午後ツールその51、IMEオフと条件付き書式セル選択ボタンとそのマクロ

$
0
0
前回
午後ツールその50、午後のパレットその他更新 ( Windows ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14639262.html
で追加した午後ツールのボタン
セルに入力規則のIMEオフを設定するボタンとそのマクロ
条件付き書式が設定されているセルを選択するボタンとそのマクロ



選択セル範囲にIMEオフを設定する
イメージ 1
よく使う設定なのに、この操作がめんどくさいので

イメージ 2
ボタン付けた
今思ったけどドロップダウンリストじゃなくて専用のボタンのほうがいいかなあ



確認ボタン
何処かに設定したけど、どこに設定したか忘れた入力規則を解除したい時用かなあ

入力規則を設定したセルの確認、シート全体
イメージ 3
D列にIMEオフを設定してあるときに
リストの確認→入力規則確認(シート)を実行すると…

イメージ 4
D列が選択状態になって
入力規則が設定されているセル数とエリア数と場所が表示される


選択セル範囲のなかで入力規則が設定されているセルを選択する
イメージ 5
C4:E6を選択してから
リストの確認→入力規則確認(選択セル)を実行すると…

イメージ 6
D4:D6が選択状態になる



解除(削除)ボタン、シート全体
イメージ 7
入力規則解除(シート)で…
イメージ 8
確認でOKを押すとシート全体のセルの入力規則が解除される

確認ボタン押してみると
イメージ 9
全部消えているのがわかる


解除(削除)ボタン、選択セル範囲
イメージ 10
D列にIMEオフが設定されているときに
C4:E6を選択した状態で
解除→入力規則解除(選択セル)を押すと…

イメージ 11
確認が出るのでOK押すとD4:D6の入力規則が解除される
解除しました!とか出ないからわかりにくいかな

確認すると
イメージ 12
期待通りの結果になっているのがわかる



条件付き書式確認
イメージ 13
ホーム→条件付き書式で設定したセルを確認(選択)するのが

イメージ 14
条件付き書式確認ボタン(そのまま)

イメージ 15
C4:E6に条件付き書式が設定されている
確認ボタン押すと…

イメージ 16
条件付き書式が設定されているセルが選択されて
セル数、エリア数、アドレスが表示される
入力規則の確認ボタンと同じ使い方になっている
これもどこに条件付き書式を設定したのか忘れた時用かな


ここで気づいたのが
セル以外を選択した状態でIMEオフボタンを押すとエラーになる
選択しているのがセルかどうか確認するのを書き忘れていた
↓の2行目を書き忘れていた

Sub 選択範囲のIMEオフ()
    If TypeName(Selection) <> "Range" Then Exit Sub
    With Selection.Validation
        .Delete 'これも必須…みたい
        .add Type:=xlValidateInputOnly '必須、入力規則の種類、今回はすべての値
        .IMEMode = xlIMEModeOff 'これだけだとエラーになる
    End With
End Sub

Sub 入力規則のあるセルを選択_シート全体()
'    If CheckVisibleWindows = False Then Exit Sub
    On Error GoTo myErr
    Set s = ActiveSheet
    If s Is Nothing Then
        MsgBox "ブックを開いてから実行してください"
        Exit Sub
    End If
'    Cells.SpecialCells(xlCellTypeAllValidation).Select
    Dim r As Range
    Set r = Cells.SpecialCells(xlCellTypeAllValidation)
    r.Select
    Dim a As Areas: Set a = r.Areas
    Dim str As String
    str = "このシートで入力規則が設定されているセルを選択しました" & vbNewLine & _
    "セル数:" & r.Cells.CountLarge & vbNewLine & _
        "エリア数:" & a.Count & vbNewLine
    
    For i = 1 To a.Count
        str = str & a.Item(i).Address & vbNewLine
    Next
    MsgBox prompt:=str, Title:="このシートで入力規則が設定されているセル"
    Exit Sub
myErr:
    MsgBox "このシートに入力規則が設定されているセルは見つかりませんでした"
End Sub


参照したところ
VBAで入力規則の設定されたセルを選択する:エクセルマクロ・Excel VBAの使い方-Rangeオブジェクト
http://www.relief.jp/itnote/archives/excel-vba-select-cells-validation.php
ありがとうございます
ここを見る前はセルを一つ一つ確認しようとしていたけど
Cells.SpecialCells(xlCellTypeAllValidation)
たったこれだけでよかったw

同じように条件付き書式のあるセルの取得も
Cells.SpecialCells(xlCellTypeAllFormatConditions)
なのでコードもほとんど一緒になっている
Sub 条件付き書式のあるセルを選択_シート全体(control As IRibbonControl)
    If CheckVisibleWindows = False Then Exit Sub
    On Error GoTo myErr
    Set s = ActiveSheet
    If s Is Nothing Then
        MsgBox "ブックを開いてから実行してください"
        Exit Sub
    End If

    Dim r As Range
    Set r = Cells.SpecialCells(xlCellTypeAllFormatConditions)
    r.Select
    Dim a As Areas: Set a = r.Areas
    Dim str As String
    str = "このシートで条件付き書式が設定されているセルを選択しました" & vbNewLine & _
    "セル数:" & r.Cells.CountLarge & vbNewLine & _
        "エリア数:" & a.Count & vbNewLine
    
    For i = 1 To a.Count
        str = str & a.Item(i).Address & vbNewLine
    Next
    MsgBox prompt:=str, Title:="このシートで条件付き書式が設定されているセル"
    Exit Sub
myErr:
    MsgBox "このシートに条件付き書式が設定されているセルは見つかりませんでした"
End Sub






午後ツールその52、マイパレットの色の一括書き出しと登録機能をつけた

$
0
0


2016/12/28
午後のパレット
バージョンアップ時のマイパレットの色の引き継ぎに便利なボタン「全色登録」を追加
マイパレットのすべての色を書き出す「全色塗り」ボタンを追加

2016/12/27
午後のパレット
マイパレット以外を表示しているときは
パレットへの60色一括登録と書き出しボタンは無効にするようにした
午後のしましま
以下のときにステータスバーの処理時間表示を消すようにした
午後のしましま終了時
午後のしましまのタブを切り替えた時



この前の続きで新しく追加した赤枠のところのボタンは
選択セル範囲に枠をつけたり消したりするボタンで
旧!!のときは上下左右の4つだったのを
外枠、上下、左右、格子、外枠削除、内側罫線削除を追加したもの

イメージ 1
エクセルのホームの罫線ボタンにあるものとほとんど同じもの
違うのは色や線の種類を指定してから枠をつけるところ


イメージ 2
指定した色で枠を入れる


操作しているところ
イメージ 3
処理は少し遅いけど期待通り、いいねえ





イメージ 4
今日作っていたのが
マイパレットへの色の一括登録と一括書き出し機能
やっと作った
マイパレットには好きな色を登録できるけど午後ツールをバージョンアップすると
消えてしまうので再登録(引き継ぎ)が必要
今まではパレット(60色)ごとの再登録だったけど
マイパレット1から21までのすべてを一括でできるようにした
これで少しは楽になった

操作の流れは
古いバージョンで一括書き出しをしておいて
新しいバージョンで一括登録って感じになる

一括書き出し機能は今回からなので
実際に使えるのは今回のバージョン以降のになるねえ


全色塗りボタン(一括書き出し)は
マイパレットの色をすべてをシートに塗るボタンで
イメージ 5
何も入っていない新しいシートを用意して
午後のパレットはマイパレットを表示した状態で
全色塗りボタンを押すと

イメージ 6
色が塗られるセル(147行x10列)が選択されて確認メッセージが出る
はいで次に進むと

イメージ 7
マイパレットのすべての色が塗られる

イメージ 8
一番下側の様子
これで書き出しは完了


こうしてできた一覧をマイパレットに登録するのが
全色登録ボタン
イメージ 9
登録したい色一覧の左上のセル(A1)を選択した状態で
全色登録ボタン押すと

イメージ 10
確認メッセージ表示
はいをクリックで登録されて…

イメージ 11
確認メッセージ表示
間違って登録したり元に戻したいときもあるだろうから
登録前のパレットの色を右隣にシートを追加して
そこに書き出すようにしてある、要らなければ削除で


これでマイパレットへの色の登録は3種類になった
  • 1色ごとの登録(パレット右クリック)
  • パレット(60色)ごとの登録
  • マイパレット全体への登録


午後のパレットは今回ので一段落かなあ

ダウンロード



エクセルVBA、チェックボックス付きのListBoxのInputBox?を作ってみた

$
0
0


ユーザーからデータを受け取りたいときはInputBoxを使うんだけど
イメージ 11
これだと1つしか受け取れなくて事足りないときがある

そこでつくってみたのがこれ↓
イメージ 1
チェックボックス付きのリスト形式のInputBoxみたいなの
ボタンを押すとチェックの入った項目の配列を返す

イメージ 10
受け取った配列(Ash)の中身
チェックした「ささやき」と「いのり」が入っている

ユーザーフォーム
イメージ 2
ListBoxとボタンを追加しただけ

ユーザーフォームのコード
イメージ 3
エラー処理していないので短い

ユーザーフォームを呼び出す標準モジュール
イメージ 4
こっちもエラー処理していない
思いつくエラー処理は
ユーザーが何も選択しないでボタンを押したとき
ボタンを押さずにフォームのXボタンを押して閉じられた時


ユーザーフォームコード
Private myWords() As String

'ボタン押した時
Private Sub CommandButton1_Click()
    Call GetWords
    Me.Hide 'ユーザーフォームを非表示にする
End Sub

Private Sub UserForm_Initialize()
    'ListBoxの初期化
    With Me.ListBox1
        .AddItem "ささやき"
        .AddItem "えいしょう"
        .AddItem "いのり"
        .AddItem "ねんじろ!"
        .ListStyle = fmListStyleOption      'チェックボックスにする
        .MultiSelect = fmMultiSelectMulti   '複数選択可にする
    End With
End Sub

'チェックされたリストを配列に入れる
Private Sub GetWords()
    Dim i As Long, j As Long
    For i = 0 To Me.ListBox1.ListCount - 1
        If Me.ListBox1.Selected(i) Then
            ReDim Preserve myWords(j)
            myWords(j) = Me.ListBox1.List(i)
            j = j + 1
        End If
    Next
End Sub

'標準モジュールから呼び出す関数
'ListBoxでチェックされた項目名群を返す
Public Function doModal() As String()
    Me.Show
    doModal = myWords
End Function


標準モジュールのコード
Sub GetMyWords()
    Dim Ash() As String
    Ash = UserForm1.doModal
    Unload UserForm1 'ユーザーフォームはここで閉じる
End Sub

↑標準モジュールの
Ash = Userform1.doModal
ってのが呼び出しているところで、InputBoxなら
Ash = InputBox
こうなるところ

doModal関数のMe.Showでユーザーフォームが表示される
イメージ 5
ユーザーがリストを選んで

イメージ 6
ボタンを押すと
GetWordsが実行されて

イメージ 7
グローバル変数のmyWordsに選択された項目名が入る

ユーザーから見るとボタンを押した時点でユーザーフォームが閉じられるのが自然だけど、処理はまだ終わっていないので閉じることはできないので
Me.Hide
これで非表示にして閉じたように見せかけている


イメージ 8
ボタンを押したときの処理が終わるとここに戻ってくるんだけど
この流れがよくわからん、こうなってくれないと困るんだけどね。
これでユーザーフォームの方は終わりで取得したmyWordsは標準モジュールの方へ送られる

標準モジュール
イメージ 9
ユーザーが選択した項目名が取得できている
ここまで来てからユーザーフォームを閉じて完了


参照したところ
標準モジュールとフォーム間のデータ受け渡しⅡ|Excelユーザーフォーム入門
http://excel-ubara.com/excelvba3/EXCELFORM010.html
ここがなかったら今回のは作れなかった

Office TANAKA - Excel VBA Tips[複数選択可能なリストボックス]
http://officetanaka.net/excel/vba/tips/tips144.htm


ダウンロード


関連記事
午後ツールその53、ウィンドウの整列、異なるブック(ウィンドウ)の整列 ( Windows ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14655664.html


Viewing all 420 articles
Browse latest View live