• ベストアンサー

エクセルVBA、フリーフォームで円を描画したい

円の方程式 X = r * Sin(θ)、Y = r * Cos(θ)を使い、フリーフォームで円を描こうと思い、下記のマクロを書きました。 まず、最初からつまずきました。 マクロ名をSub Circleにしたらそれだけでエラー。 VBAにCircleという関数か何かあるのですか? 次に下記に名前を変えて実行したら、実行時エラー1004「アプリケーションまたはオブジェクトの定義エラー」だそうです。ためしにX0、Y0を100にしたらエラーは出ませんがスタートの座標100、100から円までの軌跡と円に接するところが変になります。 フリーフォームで真円を描くにはどこをどう直せばいいでしょうか? Sub EN() r = 50 π = Application.WorksheetFunction.Pi() ' X0 = 100 ' Y0 = 100 X0 = r * Sin(0) + 100 Y0 = r * Cos(0) + 100 With ActiveSheet.Shapes.BuildFreeform(msoEditingAuto, X0, Y0) For θ = 0 To π * 2 Step π * 2 / 360 X = r * Sin(θ) + 100 Y = r * Cos(θ) + 100 .AddNodes msoSegmentCurve, msoEditingAuto, X, Y DoEvents Next .ConvertToShape.Select'ここがエラー End With End Sub

質問者が選んだベストアンサー

  • ベストアンサー
  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.5

既にご指摘があるように、刻みを荒くすると旨く行くようです。 小生もいろいろ試してみました結果です。それもある時は 旨く行って、変えてないのに別の機会には旨く行かないこともあったようで、悩まされました。ご報告だけですみません。 Sub EN() Cells.Clear Dim x As Double Dim y As Double Dim pai As Double Worksheets("sheet1").DrawingObjects.Delete j = 0 R = 100# pai = Application.WorksheetFunction.Pi() pai = 3.14159 '-------0 j = j + 1 x0 = R * Sin(0) + 200# y0 = R * Cos(0) + 200# Cells(j, "A") = x0 Cells(j, "B") = y0 With ActiveSheet.Shapes.BuildFreeform(msoEditingAuto, x0, y0) '--------1-359 For θ = 5 To 359 Step 5 j = j + 1 x = R * Sin(θ * pai / 180) + 200# Cells(j, "A") = x y = R * Cos(θ * pai / 180) + 200# Cells(j, "B") = y .AddNodes msoSegmentCurve, msoEditingAuto, x, y Next '-------- .AddNodes msoSegmentCurve, msoEditingAuto, x0, y0 j = j + 1 Cells(j, "A") = x0 Cells(j, "B") = y0 .ConvertToShape.Select End With End Sub でFor θ = 5 To 359 Step 5の5を4にするとエラーがでて、5にするとうまく行きます。 初期値5もX0,y0から離れるようにしないと行けない。 (θ = 0 to・・やθ = 1 toはX0,y0と接近してだめ。) (1)Forは小数点つきの数を指定していても、整数値を取って飛ぶ。Stepの取る数も同じ。 (2)必ず最初の点に戻って閉曲線になるべきかどうか、最初の点に繰り返しAddnodesして良いかどうか不明。 フリーフォームを使われるぐらいだから、簡単な下記のやり方は既にご存知でしょうね。 Sub test04() cLeft = 200 cTop = 100 cWidth = 100 cHeight = 100 ActiveSheet.Shapes.AddShape(Type:=msoShapeOval, _ Left:=cLeft, Top:=cTop, Width:=cWidth, Height:=cHeight).Select End Sub

AQUALINE
質問者

お礼

ありがとうございました。 勉強になりました。 msoShapeOvalはもちろん存じております。 今回、円をぐるっと書いてみたかったのでフリーフォームでやってみました。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (4)

noname#29107
noname#29107
回答No.4

#2です。 >修正のプロシージャーを実行しましたが、やはり同じ実 >行時エラーとなりました。 私の環境(Excel2002)では、先の修正で動作したのですが、バージョンなどに影響を受けるかもしれません。 #3の方の回答にあるように、節点が近すぎるとエラーになるようですので、 r = 50 をもう少し大きくするか、   For θ = π * 2 / 60 To π * 2 Step π * 2 / 60 の刻みを粗くする。たとえば、   For θ = π * 2 / 45 To π * 2 Step π * 2 / 45 位に変えてみてください。これでエラー発生するなら、順次数値を変えてみて、エラーが発生しない数値を探してみてください。 いずれにしても、半径と刻みを調整すれば、先の回答内容で動作すると思います。

AQUALINE
質問者

お礼

ありがとうございます。 友人のエクセル2003でやってもらったらうまく動くそうです。 わたしの2000では駄目でした。

全文を見る
すると、全ての回答が全文表示されます。
  • ogura_kei
  • ベストアンサー率33% (115/346)
回答No.3

#1の書き込みをした者です。実は回答して直ぐに回答内容の誤りに気付き「間違ってました」と再書き込みをしたつもりだったのですが、急ぎの用件があってあわてたのでどうやら回答の確認ボタンを押さずに席を外してしまったようです。失礼しました。 #2のrebellionさん、正確な回答をありがとうございました。 それで、一部判明したことがあるのでご報告します。 以下だけでエラーになります。 ActiveSheet.Shapes.BuildFreeform(msoEditingAuto, 100, 150) .AddNodes msoSegmentCurve, msoEditingAuto, 100, 150 そして以下とするとエラーはなくなります。 .AddNodes msoSegmentCurve, msoEditingAuto, 100, 158 つまり、接近しているとまずいようです。そして、その線でネット情報を調べたら同じ問題についての記述を見つけたのでご報告します。 http://cgi.fuji.ne.jp/~fj2094/cgi-bin1/wwwlng.cgi?print+200311/03110065.txt の一番最後の報告に「節点の距離が近すぎるとダメみたいです」と記載されています。

AQUALINE
質問者

お礼

ありがとうございます。 節点の距離が近すぎるとダメなんですね。 これってバグですね。

全文を見る
すると、全ての回答が全文表示されます。
noname#29107
noname#29107
回答No.2

>マクロ名をSub Circleにしたらそれだけでエラー。 一般的な英単語は予約語に引っかかる可能性がありますので、putcircleとかのように辞書にない形で、定義するのが普通だと思います。 >実行時エラー1004「アプリケーションまたはオブジェクトの >定義エラー」 BuildFreeformについては詳しくないので、真の原因はよくわかりませんが、ADDNODEをForループで0から始めると、BuildFreeformで指定した最初の節点になるのが、まずいのではないかと思います。また、ForループでのStepの刻みも小さすぎるのではないかと思います。 以上を踏まえて修正してみると、 Sub EN() Dim X As Single, Y As Single R = 50 π = Application.WorksheetFunction.Pi() ' X0 = 100 ' Y0 = 100 X0 = R * Sin(0) + 100 Y0 = R * Cos(0) + 100 With ActiveSheet.Shapes.BuildFreeform(msoEditingAuto, X0, Y0)   For θ = π * 2 / 60 To π * 2 Step π * 2 / 60     X = R * Sin(θ) + 100     Y = R * Cos(θ) + 100     .AddNodes msoSegmentCurve, msoEditingAuto, X, Y     DoEvents   Next   .ConvertToShape.Select End With End Sub といった感じでしょうか? あとθやπのような2バイト系の字は、変数に使用しない方が好ましいと思います。また、この場合DoEventsも不必要だと思います。

AQUALINE
質問者

補足

さっそくありがとうございました。 修正のプロシージャーを実行しましたが、やはり同じ実行時エラーとなりました。 残念です。

全文を見る
すると、全ての回答が全文表示されます。
  • ogura_kei
  • ベストアンサー率33% (115/346)
回答No.1

多分ですね、 Visual Basic editorの[ツール]-[参照設定]中の[ConvertToShape]に対応するライブラリファイルが選択されていないのではないかと思います。 試してみてください。

AQUALINE
質問者

補足

ありがとうございました。 [ConvertToShape]に対応するライブラリファイルとはどれなのでしょうか? 現在参照にチェックが入っているのは Visual Basic For Applications Microsoft Excel 9.0 Object Library OLE Automation Microsoft Office 9.0 Object Library Microsoft Forms 2.0 Object Library です。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • ExcelのVBAでフォームが表示されない

    Sub フォーム起動() UserForm1.Show End Sub 上記の内容をModule1にしてショートカットキーをを設定し、いつでも他に作ってあるユーザーフォームが起動するようにしていました。しかし先日、久しぶりに使ってみようと、設定したショートカットキーを押したら、VBAもマクロも全くいじっていないにも関わらず、「UserForm1.Show」の部分で「実行時エラー'380': Valueプロパティを設定できません。プロパティの値が無効です。」とエラーが表示されフォームが起動できません。これはいったい何が原因なのでしょうか。

  • VBA

    次のように偏差値を求めるプログラムを書くと、アプリケーションの定義エラーと表示されます。誰か理由をお教えください。 Sub hensati() With Worksheets("C") For i = 2 To 43 x = Cells(G, 1) y = Cells(G, 2) Cells(i, 3) = (Cells(i, 2) - x) / y * 10 + 50 Next i End With End Sub

  • エクセルVBA

    VBAの素人です。 以下のようなVBAを実行しようと、何とか形にしました。 単独のBOOKではうまくいくのですが、同時に他のBOOKを開くと 「インデックスが有効範囲にありません」とエラーになります。 エラー箇所は、With Sheets("Sheet1").Range("B1")部分です。 修正をご教示頂ける方、何卒よろしくお願い致します。 全くVBA無知なのにすみません。 Private Sub Workbook_Open() test01 test02 Application.OnTime Now + TimeValue("00:10:00"), "終了" End Sub Sub 終了() Application.OnTime Now + TimeValue("0:00:02"), "test01", , False ThisWorkbook.Close Savechanges:=False Application.Quit End Sub Sub test01() With Sheets("Sheet1").Range("B1") .Value = Time .NumberFormatLocal = "mm:ss" End With Application.OnTime Now + TimeValue("0:00:02"), "test01" End Sub Sub test02() With Sheets("Sheet1").Range("B2") .Value = Time .NumberFormatLocal = "mm:ss" End With End Sub

  • エクセルVBAでフォームの無効化(2)

    http://odn.okwave.jp/kotaeru.php3?q=1942213 の質問の追加質問なのですが、 ワークシート上に配置したフォームのコンボボックス(DropDowns)をマクロにて無効とさせる方法です。 シート保護されている場合、 DropDownオブジェクトを個別に指定して Sub TEST3() With ActiveSheet .DropDowns("Drop Down 7").Enabled = False .DropDowns("Drop Down 8").Enabled = False .DropDowns("Drop Down 9").Enabled = False End With End Sub とすると、OKなのですが、コレクションオブジェクトとしてまとめてやろうとして、 Sub TEST4() With ActiveSheet .DropDowns.Enabled = False End With End Sub とするとエラーになります。 シート保護のない場合は両方ともOKです。 どういう違いなのでしょうか?

  • Excelのマクロでフリーフォームの作成について

    Excel2010です。 マクロの記録でフリーフォームを作成するマクロを作りました。 角が1つある直線のフリーフォームです。 Sub Macro1() With ActiveSheet.Shapes.BuildFreeform(msoEditingAuto, 50, 50) .AddNodes msoSegmentLine, msoEditingAuto, 100, 150 .AddNodes msoSegmentLine, msoEditingAuto, 150, 150 End With End Sub マクロを実行した後、「頂点の編集」で真ん中の頂点を移動すると片側の線が曲線になってしまいました。 マクロを使わず、同じフリーフォームを直接描画して頂点を移動すると曲線にはなりません。 マクロで描画後に毎回「線分を伸ばす」で直線にするのは面倒なので、はじめから曲線にならないようにするには、マクロをどう直せば良いでしょうか? またマクロでできあがる線は、真ん中の頂点がない直線でもかまいません。 目的はマクロで出来た線に「頂点の追加」で角を数カ所追加することです。 角の位置はその都度変わります。 このブックはExcel2003、2007、2010で使用する予定です。 もしくは、フリーフォームが曲線にならないようにExcelの設定を変えてしまう方法でもかまいません。 どうぞよろしくお願いします。

  • エクセルVBAでApllication.Caller

    エクセル2000です。 マクロをワークシート上に貼ったフォームのボタンなどから呼び出す場合、ボタンの名前はApllication.Callerでわかるので、同じ一つのマクロでも呼び出されたボタンに応じた動きができるのですが、他のマクロから呼び出した場合、Apllication.Callerではエラーになってしまいます。 例 Sub test() x = Application.Caller If x = "AAA" Then MsgBox "AAA" If x = "BBB" Then MsgBox "BBB" Cells(1, 1).Value = "1" End Sub 他のマクロから呼び出された場合、エラーとしないためにはOn Error Resume Next以外ではどのようにすればいいでしょうか?

  • エクセルVBA フォームへ動的に貼り付けたボタンのクリックイベントを検知する方法を教えてください

    (1)excel97にのVBAでフォームを作成します。 デフォルトの場合はUserForm1という名前がつきます。 (2)標準モジュールとして下記のコードを作成します。 Sub ボタンを付けて表示() Dim btn As Control  With UserForm1       ’ボタンを"button"という名前で作成します   Set btn = .Controls.Add("Forms.CommandButton.1", "button")   ’ボタンの設定をします   With btn    .Top = 5    .Left = 5    .Height = 20    .Width = 200    .Caption = "push me!"   End With   ’フォームの設定をし、表示します   .Height = 60   .Width = 220   .Show  End With End Sub (3)マクロを実行するとフォームが表示されます。 そこでこのボタン("push me!"と表示されています)をクリックします。 このクリックを検知してマクロを動かしたいのですが可能でしょうか? なおUserForm1に下記のコードを付けてみたのですがクリックは検知できませんでした。 Private Sub button_Click()  MsgBox "You click the button." End Sub

  • エクセルVBA フォーム上でOnkeyがうまく出来ない

    エクセルVBAでプログラムをしています。 Application.Onkeyでショートカットを指定したいのですがフォーム上ではうまく指定できません。 フォーム上での指定は不可能なんでしょうか? ショートカットを認識するケース 標準モジュールに Sub test2() MsgBox "test2" End Sub Sub Auto_Open() Application.OnKey "{b}", "test2" End Sub としてシート上で「b」を押した場合はうまくいきます。 ショートカットを認識しないケース 標準モジュールに Sub test() MsgBox "test" End Sub UserForm1フォームに Private Sub UserForm_Initialize() Application.OnKey "{a}", "test" End Sub としてフォームをロード(表示)して「a」を押しても何もおきません。 またフォームが表示されている状態で「b」を押しても何もおきません。 上記のコードはテストで作ったものなのでこれ以外はフォームを開く文以外何も書いておりませんので他との兼ね合いではないと思います。 どうすれば思ったとおりの動作になるのでしょうか? そもそもOnkeyはユーザフォームがアクティブのときは動かないのでしょうか? 動かない場合、フォームがアクティブなときのみフォームごとに違う関数を呼ぶショートカットを作る方法はありませんでしょうか? (コントロールごとにkey_downイベントで確認する方法はコントロールの数が各100個ほどあるのと、フォームが10個以上あるため出来ればやりたくありません。) 環境はwinXP、excel2003です。 よろしくお願いいたします。

  • Excel 2007 VBA マクロにショートカットを割り当てる

    お世話になります。 UserForm に GotoNextItem というボタンがあり、そこをクリックすると proc_GotoNextItem というマクロを実行することにして、うまくいっています。 同じ動作を、ショートカットキー Shift+Ctrl+Nでも行わせようと思い、下のように書いてみたのですが、うまくいきません。 (ウンともスンともいいません) 何かわかるでしょうか? よろしくお願いします。 Private Sub GotoNextItem_Click() proc_GotoNextItem End Sub Private Sub UserForm_Initialize() MsgBox "start" Application.OnKey "^+{n}", "proc_GotoNextItem" End Sub Private Sub UserForm_Terminate() Application.OnKey "^+{n}" End Sub Public Sub proc_GotoNextItem() MsgBox "GotoNextItem!" End Sub フォームにボタンがあるなら Acceratator でいいじゃんと言われそうですが、フォームにフォーカスがないときがあり(それでも早見表代わりに ShowModal=False で表示させておこうと思います)それでも実行したいと思ったからです。 なお、Onkey の代わりに、 Application.MacroOptions HasShortcutKey:=True, ShortcutKey:="N" などと書くと、 「表示されていないマクロは編集されていません、[ウィンドウ再表示]を表示して、ウィンドウを表示してください」 と言われます。 よろしくお願いします!

  • エクセルのVBAのことで

    以下のVBAを実行するとテキストボックスの"あ"という文字で円を描くことができます。 Sub test1() pai = 3.14159 r = 100 Worksheets("sheet1").Activate For s = 0 To 360 Step 15 rd = s / 180 * pai ActiveSheet.Shapes.AddTextbox(msoTextOrientationHorizontal, _ 200 + r * Sin(rd), 50 + r - r * Cos(rd), 20, 20).Select Selection.Characters.Text = "あ" Selection.ShapeRange.Fill.Visible = msoFalse Selection.ShapeRange.Line.Visible = msoFalse Next s End Sub この円の半分の半径の円を元の円とドーナツ型(◎)になるように描くにはどのようなスクリプトにすればいいのでしょうか?

このQ&Aのポイント
  • お困りの方には、トナー交換のメッセージが消えない問題について解決方法をご紹介します。
  • Windowsをお使いの方や有線LANで接続している方に特に役立つ情報をまとめました。
  • トナー交換のメッセージの表示が消えない場合、ひかり回線を使用していることが影響している可能性もあります。
回答を見る

専門家に質問してみよう