ラベル MS Excel の投稿を表示しています。 すべての投稿を表示
ラベル MS Excel の投稿を表示しています。 すべての投稿を表示

2009/04/19

この程度の関数もナイって・・・


いやね、Excelとか使う向きって、商品管理や見積りの集計に使うってのは、当然のように大多数だと思うのだよ、
しかし、数量、単価で小計を出せて、入荷や進捗管理も併記できる専用のワークシート関数ってナイんだよ、実際。

まぁ、そういった関数の理想的な動きとしては、
    {商品名} ─未入力→ 関数はNull値を返す。    
 │
何らかの入力アリ

{単価} ┬文字列→ 関数は値0を返す。
│ └未入力→ 値0を返す。

数値入力アリ

{数量} ┬文字列→ 関数は値0を返す。
│ └未入力→ 単価を返す。(数量1として扱う)
│ (1個しか要らないのに、イチイチ数値入力してられるかっての)

数値入力アリ

単価/数量の積を返す。
ってトコだろうか。
コレなら、在庫があるモノだった場合、数量セルに "在庫"、作業完了対象なら "済" とでも入力しておけば、
単価を入力していても小計には出ない。

そりゃあ、セルに延々式を書き込めば、ウゴくって云やぁウゴくケド、
入力値の種類識別などの条件を処理させるには、式の長さと煩雑さがハンパなくなって、
対象数が多い場合、計算終わるまで結構な時間掛かってしまう場合もあったり・・・

前に就いていた職で、支店から集められたデータを一気に集計させるべく、
150以上のワークシート跨いだ複雑な条件式を大量に実行させたら、
計算終わる前にDELL機(Pen4 2.2GHz 512MB WinXPSP2)が再三オチたモノだ・・・
オチずにウゴいても、結果が出るまで1時間以上掛かってた記憶が・・・


んで今日、日曜大工な向きで、久々に品物管理の必要に迫られ、
単なるリストではなく、集計を必要とするワークブックを作成、


画像クリックで原寸大表示▼



それに使う為、ExcelVBA向けとして、あると便利そうな機能を盛り込んだ汎用性の高い関数を描いてみた。
アドイン(.xla)のモジュールに書き込んで、ワークシート関数として使う為のスクリプト。


    '------------------------------------     
'sTotal
'- Created by LazwardFox -
'下記条件に従い、小計を表示する。
'商品名セル[Article]に入力がある場合のみ有効とする。
'数量[Quantity]/単価[Unit]への入力が文字列だった場合は、無効として扱われる。
'数量セル[Quantity]未入力の場合 は 1(個) として扱われる。
'単価セル[Unit]未入力の場合 は 0(円) として扱われる。
'
' Update -------- ----
' Release 20090419 1707
Public Function sTotal(Optional ByVal Article As Variant = "", _
Optional ByVal Quantity As Variant = 1, _
Optional ByVal Unit As Variant = 0) As Variant

Application.Volatile
If Article = "" Then
sTotal = ""
ElseIf VarType(Quantity) = 8 Or VarType(Unit) = 8 Then
sTotal = 0
ElseIf Unit = 0 Then
sTotal = 0
ElseIf Quantity = 0 Then
sTotal = Unit
Else
sTotal = Unit * Quantity
End If
End Function


まぁ、えれぇ簡単に見えるが、コレをワークシート上、1セルの式記述だけで実現するには、
やたら長ったらしい式の入力を要求されるワケよ。
不正入力への対応とかも含め、ラクしたいなら、VBAでワークシート関数ツクるに限るねぇ。

って、使うワークシートのモジュールに書き込んで、ローカル関数として使うだけでも別段支障は無いが、
どうせなら、アドイン作るのも覚えてみると、結構便利デスよ。
・・・とか云いつつ、その件については放置、触れる気すら無い外道さ加減が おきつねさまクオリティw
ま、別段質問された訳でもナイし、だいたい、ググりゃ判るし、
アドインの組み込み方も知らないでExcel使ってる向きには興味ないしΨ(`∀´)Ψ

つか、云う程難しいこっちゃナイってのがホントのトコ。
どのくらい簡単かって? ソレさえも判らないなら、アタマのデキがシれてるってぇくらいw
Excel操作してるだけで なんとなく判るってホド簡単。

でも、リクエストがあるなら、
初心者向けに、非常に簡単な方法を、図解入りで、極めて判りやすく解説せんでもないが、
まぁ、ナイだろう(自己完結)


あと、敢えてエラー処理は記述しなかった、そのほうが入力ミスに気付き易いと云う判断からだ。
入力を人の手に頼る場合、過度なエラー回避処理は諸刃の剣でしかない。
こういったスクリプトを組む場合は、そのヘンも一考して開発/配布したほうがイイ。

トクに会社などでの利用の場合、実際のトコが どうなのかは別として、
"自分と同じだけの高度なスキルを持った人間など まず居ない"と思って掛からないと、
確実に、たいした原因でもないトラブルに巻き込まれて痛い目を見るよ。

最近の(大手)企業の社員の質は、考えられない程 低いからねぇ・・・
トクに、能力カスのクセに、向上心は出世にだけ向いてて、永いコトそこに居るだけ的な連中はねぇ・・・

自分に出来ない事を人に聴けるようになったら、オトナ(ふしぎの海のナディア より) ってコトらしいが、
現実は、歳ばかりとってるか、"自分は立派な大人"とか勘違いしてて、オツムの中身ガキなの多くて、
ソレすらムリとか・・・

でもまぁ、そう云う、ヘンなプライドだけが先に立って、歳下の社員に質問できないで居る、
貝になったタッチおじさんな向きの質問でも、丁寧に答える用意はあるのだが・・・

2009/03/09

Excelワークシート関数に・・・


DateSerialがナイことに、さっき気がついた・・・

ナニをイマサラと云われそうだが、ソレもソノ筈、
    '----------------------------------------         
'Worksheet向けDateSerial
'- Created by LazwardFox -

'update 200903090716 微修正
'Release200511291534

Public Function iDateSerial(Optional ByVal iYear As Variant = "", _
Optional ByVal iMonth As Variant = "", _
Optional ByVal iDay As Variant = "", _
Optional ByVal iFormat As Variant = "") As Variant
On Error Resume Next
Application.Volatile
Dim Result
Result = DateSerial(iYear, iMonth, iDay)
If IsError(Result) Then '※
Result = Now() '※
End If '※
If iFormat = "" Then
Else
Result = Format(Result, iFormat)
End If
iDateSerial = Result
End Function
こんなのツクってアドインとして組み込んで使っていたので、そのコトを忘れていた(;゚д゚)ァ....


Worksheet上で
   =iDateSerial(2009,3,0,"yyyy/mm/dd")    
こう使う。

当然、引数はセル参照を指定できるので、当時は それなりに使えたよ。

ちなみに、今日追加したのは、文字列返しの部分と、不正入力対応・・・
デモ、ホントに使うのなら、不正値での動作は、エラーを返すほうがイイのかも知れない・・・
そうしたい場合は、※印の行を消して使ってくださいなっと♪


P.S. コッチのほうが無難かも・・・
    '----------------------------------------         
'Worksheet向けDateSerial
'- Created by LazwardFox -

'update 200903090824 再微修正
'Release200511291534

Public Function iDateSerial(Optional ByVal iYear As Variant = "", _
Optional ByVal iMonth As Variant = "", _
Optional ByVal iDay As Variant = "", _
Optional ByVal iFormat As Variant = "") As Variant
On Error Resume Next
Application.Volatile
Dim Result
If iYear="" And iMonth="" And iDay="" Then
Result = Date()
Else
Result = DateSerial(iYear, iMonth, iDay)
End If
If iFormat = "" Then
Else
Result = Format(Result, iFormat)
End If
iDateSerial = Result
End Function

VBScriptで月末日取得 最強処理・・・


つか、VBSで無くとも応用できます、閏とか一切気にしなくてイイです。

今日の月の月末日は ってのは
   n = Now()
ny = Year(n)
nm = Month(n)

ML = DateValue(ny,nm+1,0)
コレだけ(爆)

優良サイトではないので変数宣言省いてマスΨ(`∀´)Ψ

単に日付が欲しいだけで、イチイチ閏なんて計算してらんないって、バカらしくてw
ただ、税額処理だの、給与計算だのってぇのでは、意外に使える(実際使ってた)

+1 0 ってトコがツボ。大体殆どの開発環境で使えるし、
Excelワークシート関数なら
   =DATEVALUE(YEAR(NOW())&"/"&MONTH(NOW())+1&"/1")-1    
こうなる。

Excel/AccessなどのVBAでも有効な手段。
   Dim nYear As Integer ,nMonth As Integer

nYear = 2009
nMonth = 2

'日付値が欲しい場合
LastDay = DateSerial(nYear, nMonth + 1, 0)

'日のみ欲しい場合
LastDay = Day(DateSerial(nYear, nMonth + 1, 0))


Excelに対し、DateControls.xlaと云うExcelAddinファイルをツクって、
モジュールにFunctionsと銘打って、その中に記述していた関数、
Public宣言とApplication.Volatile記述で、ワークシート関数として使っていたブツ。
    '----------------------------------------         
'LastDayGet - Serial値から日付を取得し同月の末日を返す。
'- Created by LazwardFox -

'閏月対応

'update 200607031715 エラートラップ修正
'Release200511291534

Public Function LastDay(Optional ByVal Target As Variant = "") As Integer
On Error Resume Next
Application.Volatile
If Target = "" Or Target = 0 Or IsError(Target) Then
Target = Now()
End If
LastDay = Day(DateSerial(Year(Target), Month(Target) + 1, 0))
End Function


しかし、最近はExcelも使わなくなったなぁ・・・

って、職があった頃から、Excelには見切りつけて、
数百MB規模のデカいデータは、VBSで適宜処理して、AccessやSQL鯖にブチ込んで処理してたケドねww

つか、プーしてる今となっては、無用の長物だけどねww
<月末 日付取得 うるう Excel Access VBA>