スポンサーサイト 


上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

--/--/--

Category: スポンサー広告

TB: --  /  CM: --

top △

至難 


いろいろと質問をみていると
・結果を知っていて・・・
・どういう回答が寄せられるか・・・
を楽しんでいるのかなぁ~ と思いたくなるようなものもありますね
釣り?  本当にわからないで聞いているの?

例えば
1)
文字列 "2013年10月12日(土)" なら 20131012 の8桁に、
文字列 "2013年1月18日(土)"  なら 20130118 の8桁に変換したい

2)
Dim obj As Object

Set obj = CreateObject("Excel.Application")
obj.Workbooks.Open FileName:="D:\hoge\hogehoge.xls"
上記記述で、ファイルを開いて obj を取得している・・・
ファイルの内容を随時参照/更新したいので、ファイルが開いていたら、それを参照したい

3)
変数 a = 2, b = 3 の時、掛け算を使って 1 を求めたい


回答を考えてみるとしたら、

1)
文字列 "2013年10月12日(土)" なら 20131012 の8桁に、
文字列 "2013年1月18日(土)"  なら 20130118 の8桁に変換したい

の場合、素直に考えれば、
・Date型「日付」を
・Format(日付,"yyyy年m月d日(aaa)") で表示しているのかな?(もしくは書式?)
と思うので、"(" までの左側を CDate / DateValue で変換したものを
Format で "yyyymmdd" すれば良さそうに見えます。

ただ、2013年1月18日 は金曜なので、単に日付に似せた数字が使われている・・・
と思った方が良いのかもしれませんね。
まさか、(土) に合わせて、近い 2013年1月19日 に置換えろ・・・じゃないですよね。
"(" の右側は信じるな・・・・ なら CDate / DateValue を使っても良いかもしれない・・・
安易に CDate / DateValue は使えない・・・ という解釈しておいた方が better ?
数字部分を左から順に取り出して、4桁2桁2桁に揃えた方が無難でしょうか?

ということで、RegExp を使ってやってみましょうか・・・

Public Function CalcMoji(ByVal sSrc As String)
  Dim sR As String
  Dim vAry As Variant
  Dim v As Variant
  Dim i As Long

  vAry = Array(4, 2, 2)

  sR = ""
  sSrc = StrConv(sSrc, vbNarrow)
  With CreateObject("VBScript.RegExp")
    .Pattern = "\d+"
    .Global = True
    i = 0
    For Each v In .Execute(sSrc)
      If (i > UBound(vAry)) Then Exit For
      sR = sR & Format(Int(v), String(vAry(i), "0"))
      i = i + 1
    Next
  End With
  CalcMoji = IIf(Len(sR) > 0, Int(sR), 0)
End Function

「8桁」という表現だったので、生成した文字列を Int 変換していましたが・・・
文字列のままで良ければ、そのまま CalcMoji = sR でも。
(なので、関数の型は明示してませんでした)

この方法であれば、数字間は数字じゃない文字列が入っている・・・で動きますね。
"2013.4.5" でも "2013a6b7" でも "2013あああ8aaa9" でも・・・・
ただ、"13ABCD8あいう9" では 130809 になります。
年?に相当する部分は、単純に4桁にしているので 2013 にはなりません。
また、Int(sR) で戻しているので、先頭 "00" は削られます。
(文字列で返せば、先頭の "00" は消えません)

この関数に、解釈したい文字列を与えると結果が返ります。
例えば、Excel の A1 にその文字列があったとして、B1 に =CalcMoji(A1) すれば表示されます。
ま、Access では、テキストボックスのコントロールソースに同じように記述しておけば・・・

※ 上記のコードでは不完全です
4桁2桁2桁 に揃えようとしていますが、数字部分に桁以上が設定されていたら・・・
 2013 の4桁部分が 12013 とかでは、元の桁が生きちゃいますね・・・
4桁の場合、下4桁を有効とするには
      sR = sR & Format(Int(v) Mod 10 ^ vAry(i), String(vAry(i), "0"))
とか
      sR = sR & Right(String(vAry(i) - 1, "0") & v, vAry(i))
とか
      sR = sR & Right("000" & v, vAry(i))
とかにでもすれば良いですね・・・
 
2)
Dim obj As Object

Set obj = CreateObject("Excel.Application")
obj.Workbooks.Open FileName:="D:\hoge\hogehoge.xls"
上記記述で、ファイルを開いて obj を取得している・・・
ファイルの内容を随時参照/更新したいので、ファイルが開いていたら、それを参照したい

ここで、注目すべきは ファイルを開いて obj を取得している 表現でしょうか

既に開いている hogehoge.xls があったらそれを対象にしたい・・・そう仮定してみるなら
Dim obj As Object, objBook As Object

Set objBook = GetObject("D:\hoge\hogehoge.xls")
Set obj = objBook.Parent
 もしくは
Set obj = objBook.Application
ここからわかると思いますが、ファイルを開いて obj を取得している・・・ではないですね。
obj のもとで開いている・・・ が、私にはシックリきます。

hogehoge.xls が開かれていたら上記で辿れますね。
hogehoge.xls が開かれていなかった場合、hogehoge.xls は非表示状態
また、Excel 自体が起動されていなかったら、Excel 本体も非表示
こういった動作パターンは確認されないんだろうか・・・
(上記パターンは正しいのだろうか?? そんな雰囲気に見えたけど・・・)

で、表示するのなら
obj.Visible = True
obj.Windows("hogehoge.xls").Visible = True
すれば良いですね・・・

でもなぁ~
既に開いているものを使う・・・・
これって、操作しにくくなるだけじゃないのかなぁ~
どういう状態で開いている・・・ 云々考えなきゃ・・・
操作する前の状態に戻す/戻さない・・・ 面倒くさそう・・・
それより、自分の操作専用の Excel を起動しておいて・・・・
操作終了で Excel も終了させる・・・ の方が、他の Excel 状態をいじらない分楽でしょう・・・

とは言っても・・・ 別な方法としては
Excel が起動されていれば・・・ の判別は以下でも出来ますね
  Dim obj As Object

  On Error Resume Next
  Set obj = GetObject(, "Excel.Application")
  If (obj Is Nothing) Then MsgBox "Excel 未起動"
で、開いている Workbooks に、いじりたいファイルがあるか・・・ を見つければ
上記での GetObject の戻りは、Excel 本体になりますね

また、Excel が複数起動されていれば、また処理は増えると思います。
通常、エクスプローラとかからファイルをダブルクリックして・・・ の起動であれば、
Excel は1つで、扱っている Workbook が増えていくだけ・・・ の動きの様です。
Excel 本体が複数個の処理が必要なら、考えてみるってことで・・・・


3)
変数 a = 2, b = 3 の時、掛け算を使って 1 を求めたい

こういう質問は、なかったんですけどね・・・
前提条件が、掛け算を使って
普通に考えれば、できない・・・ ですかね
トンチ的に考えれば、関数を作って
 関数 * 関数 = 1
にすればよいのかな? 例えば、

Private Function fncA(a As Long, b As Long) As Double
  If (b = 0) Then Exit Function
  fncA = a / b
End Function

Public Sub test()
  Dim a As Long, b As Long

  a = 2
  b = 3
  Debug.Print fncA(a, b) * fncA(b, a)
End Sub

単純に考えると、(2 / 3) * (3 / 2) で 1 になると思います。
それよりも 3 - 2 = 1 で良さそうですけどね・・・

「できない」・・・へは耳を傾けず・・・ 言いたい放題・・・
前提条件を変更した - で良さそうです・・・ には、
「できない」へ対抗する為に「掛け算」にしていて「減算」がやりたい事だった・・・

前提条件を設定したのは誰なの???・・・ って言いたくなるような・・・


どれが釣り的なもので、どれが本当に困っているものなのか・・・・
見分けるって難しい・・・

できていたんだろうか???・・・ 私に・・・
関連記事

2013/10/27

Category: なんだかな

TB: --  /  CM: 0

top △

この記事に対するコメント

top △

コメントの投稿

Secret

top △


上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。