[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『関数をVBAに』(プレ)
関数を入れて休暇などをカウントしているのですが、VBAに入れるにはどうしたらいいのでしょうか? 教えて頂きたいのです。宜しくお願いします。
現在、入っている関数
ai7=COUNTIF(C7:AG7,"有休") aj7=COUNTIF(C7:AG7,"計画休") ak7=COUNTIF(C7:AG7,"午前休") al7=COUNTIF(C7:AG7,"午後休") am7=AI7+AK7*0.5+AJ7+AL7*0.5
同じ関数が、7−18まで杯っています。
宜しくお願いします。
いろんな方法があるけど、もっともVBAらしくないコード(?)
Sub Sample1() Dim z As Variant Dim i As Long
For Each z In Array("有休", "計画休", "午前休", "午後休") Range("AI7:AI18").Offset(, i).Formula = "=COUNTIF(C7:AG7,""" & z & """)" i = i + 1 Next
Range("AM7:AM18").Formula = "=AI7+AK7*0.5+AJ7+AL7*0.5"
With Range("AI7:AM18") .Value = .Value End With
End Sub
(ぶらっと
で、VBAらしいといえばSample1よりVBAらしいかもしれないSample2。 でも、自分が書くならSample1かな?
Sub Sample2() Dim col As Range Dim c As Range Dim v As Variant Dim i As Long Dim x As Long
Application.ScreenUpdating = False
v = Array("有休", "計画休", "午前休", "午後休") For Each col In Range("AI7:AL18").Columns For Each c In col.Cells i = c.Row c.Value = WorksheetFunction.CountIf(Range("C" & i).Resize(, Columns("AG").Column - Columns("C").Column + 1), v(x)) Next x = x + 1 Next
For Each c In Range("AM7:AM18") With c.EntireRow c.Value = .Range("AI1").Value + .Range("AK1").Value * 0.5 + .Range("AJ1").Value + .Range("AL1").Value * 0.5 End With Next
Application.ScreenUpdating = True
End Sub
(ぶらっと)
7とか18の部分に変数使えば、少しはVBAらしくなるかも。 今のままじゃ修正も大変だし。
Sub test() Range("AI7:AI18").Formula = "=COUNTIF(C7:AG7,""有休"")" Range("AJ7:AJ18").Formula = "=COUNTIF(C7:AG7,""計画休"")" Range("AK7:AK18").Formula = "=COUNTIF(C7:AG7,""午前休"")" Range("AL7:AL18").Formula = "=COUNTIF(C7:AG7,""午後休"")" Range("AM7:AM18").Formula = "=AI7+AK7*0.5+AJ7+AL7*0.5" End Sub
ありがとうございます。
Sheet1を入力用にしてSheet2から2012/4、Sheet3で2012/5・・・・Sheet13で2013/3にしています。 AMに集計した数字をだしてます。2012/4(Sheet2)のAM7で出した合計を、B7にこのように、=入力用!E5-'2011.4'!AM7して数字をだしています。
最後の、2013/3(Sheet13)B7の数字を有休残数として、入力用(Sheet1)のF7に数字をだしています。 どうでしょうか?難しいですか?
(プレ)
>どうでしょうか?難しいですか?
VBAでできていることが関数ではできないこともあるけど、関数でできていることはVBAでも同じようにできる。
ただし、スペックが明確じゃないとできない。 最初の質問にあった計算をやらせたいのは入力用シート?それとも、2012.4〜2013.3シート?それとも、全て? B7にある式は、全てのシートにあるの? E5 というのも初登場で、そこに何が入っているのかわからないけど気にしなくてもいいの?
>最後の、2013/3(Sheet13)B7の数字を有休残数として、入力用(Sheet1)のF7に数字をだしています。
これも、よくわからないけど、単純に、入力用シートのF7に ='2013.3'!B7 といれておけばいいんじゃない? 単に、これだけならVBAコードで処理する必要もない。 VBAでやりやいなら、 Sheets("入力用").Range("F7").Value = Sheets("2013.3").Range("B7").Value だけど。
(ぶらっと)
Range("AI7").Formula = "=COUNTIF(C7:AG7,""有休"")" Range("AJ7").Formula = "=COUNTIF(C7:AG7,""計画休"")" Range("AK7").Formula = "=COUNTIF(C7:AG7,""午前休"")" Range("AL7").Formula = "=COUNTIF(C7:AG7,""午後休"")" Range("AM7").Formula = "=AI7+AK7*0.5+AJ7+AL7*0.5"
Range("AI8").Formula = "=COUNTIF(C8:AG8,""有休"")"
Range("AJ8").Formula = "=COUNTIF(C8:AG8,""計画休"")" Range("AK8").Formula = "=COUNTIF(C8:AG8,""午前休"")" Range("AL8").Formula = "=COUNTIF(C8:AG8,""午後休"")" Range("AM8").Formula = "=AI8+AK8*0.5+AJ8+AL8*0.5"
End Sub
こんな感じで7−18まで入っています。
Sub test()
Range("AI7").Formula = "=COUNTIF(C7:AG7,""有休"")" Range("AJ7").Formula = "=COUNTIF(C7:AG7,""計画休"")" Range("AK7").Formula = "=COUNTIF(C7:AG7,""午前休"")" Range("AL7").Formula = "=COUNTIF(C7:AG7,""午後休"")" Range("AM7").Formula = "=AI7+AK7*0.5+AJ7+AL7*0.5"
End Sub これを VBAPRojectのSheet入れたのですが、数字が表示されませんでした。 なぜでしょうか?
(プレ)
まず、お願いしたのは、何をしたいかを言葉で(関数とかVBAコードとかじゃなく)説明してもらえないかな? ということ。 で、次に、アップされたコードだけど、私のコードはわかりにくかったとして、(マナ)さんのアドバイスが 全く活かされてないのが残念。
ところで、アップされたコードは、どこに記述したのかな? 標準モジュールとかシートモジュールとか、いくつかあるんだけど。 今回のテーマなら標準モジュール。ただし、複数シート対応は、もちろん必要だけど。 なので、計算式を適用するシートは、どれとどれ? と質問している。
>これを VBAPRojectのSheet入れたのですが、数字が表示されませんでした。 >なぜでしょうか?
コードは、書いただけでは動かない。このプロシジャを実行しなきゃいけないよ。 ただ、アップされたものでは、期待する結果は得られないと思う。なんとなく。 じゃぁ、どんなコードがいいんだ? ということになるけど、それを提案するために、いくつか 質問しているので、それに回答もらえたらうれしいな。
(ぶらっと)
言葉足らずで申し訳ございませんでした。
シートに関数を入れておきたくないのです。
有休の管理Sheetを作成しています。
A7〜A18に名前、B7〜B18有休残数 C7列〜AG7列まで有休などを選択できるように入力規則を入れています。 C5〜AG5までは曜日が入っています。C6〜AG6までは日付が入っています。
その後ろに、書かして頂いた関数を入力してカウントできるようにしたのです。ai7=COUNTIF(C7:AG7,"有休") aj7=COUNTIF(C7:AG7,"計画休") ak7=COUNTIF(C7:AG7,"午前休") al7=COUNTIF(C7:AG7,"午後休") am7=AI7+AK7*0.5+AJ7+AL7*0.5
上記が、Sheet2から2012/4、Sheet3で2012/5・・・・Sheet13で2013/3に入っています。 入力用は、最初の有休がいくつあるか入力しています。ここから引くように出来るのではないかと作成したのです。
今後、VBAを勉強していくうえで、今はメンテしやすいほうがいいのかと思い、(マナ)さんのを参考にさせていただきました。決して(ぶらっと)さんのが良くないとかではありません。
コードを入力したのは、標準モジュールです。
ご面倒をお掛けして申し訳ございません。
(プレ)
>今はメンテしやすいほうがいいのかと思い、(マナ)さんのを参考にさせていただきました。
私もそう思います。指摘したのは、(プレ)さんは、「こんな感じで7−18まで入っています。」 一方、(マナ)さんのコードをよく見てほしいんだけど、 Range("AI7:AI18").Formula = "=COUNTIF(C7:AG7,""有休"")" これは、AI7からAI18に、一挙に12個の式をいれることができる構文。
シートに式を残したくないんだよね。 そういう場合は、私のコードでやっているように、式をセットした後、 当該セル領域.Value = 当該セル領域.Value と記述すれば、式が値に変更される。
次に、ブックの中のすべてのシートに対応させる場合、たとえば以下のように。 (マナさんの構文を借用)
Sub Sample() Dim sh As Worksheet
For Each sh In Worksheets 'ブックの中からシートを1枚ずつとりだす '必要なら、sh.Name にシート名が入っているので、それを判定して、このシートは処理しないとか、このシートを処理するといったことが可能。(If 文を使う) sh.Range("AI7:AI18").Formula = "=COUNTIF(C7:AG7,""有休"")" sh.Range("AJ7:AJ18").Formula = "=COUNTIF(C7:AG7,""計画休"")" sh.Range("AK7:AK18").Formula = "=COUNTIF(C7:AG7,""午前休"")" sh.Range("AL7:AL18").Formula = "=COUNTIF(C7:AG7,""午後休"")" sh.Range("AM7:AM18").Formula = "=AI7+AK7*0.5+AJ7+AL7*0.5"
sh.Range("AI7:AM18").Value = sh.Range("AM7:AM18").Value '式の結果を値に変換
Next
End Sub
(ぶらっと)
こんにちは。横から失礼します。
シートに式を残したくない理由は何ですか? ブックが重いからですか? 数式を他人に見られたくないとか? それともなにか他の理由でしょうか。
ご質問を拝見するに、目的は有給の残日数をリアルタイムで知ることと思われますが だとしたら、だれかが休暇を取るたびに計算し直す必要があります。 そのたびに1年分のシートに(VBAで)数式を入れ 値に変換する……間違いではありませんが 無駄な作業がおおいと思いませんか。
ではどうすればいいか、と考えると シートに式を残したくない理由によって最適解は変わってきます。 (ことによると、数式を残すのがいちばん合理的ということもあり得ます。)
−佳−
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.