Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


3153 / 13644 ツリー ←次へ | 前へ→

【63725】桁数が多いと勝手に指数で計算してうまく判定できない pon 09/12/3(木) 16:00 質問[未読]
【63726】Re:桁数が多いと勝手に指数で計算してうま... ichinose 09/12/3(木) 17:40 発言[未読]
【63787】Re:桁数が多いと勝手に指数で計算してうま... pon 09/12/15(火) 12:33 お礼[未読]
【63788】Re:桁数が多いと勝手に指数で計算してうま... pon 09/12/15(火) 12:49 質問[未読]
【63789】Re:桁数が多いと勝手に指数で計算してうま... Jaka 09/12/15(火) 13:42 発言[未読]
【63792】Re:桁数が多いと勝手に指数で計算してうま... pon 09/12/15(火) 16:52 質問[未読]
【63794】Re:桁数が多いと勝手に指数で計算してうま... よろずや 09/12/15(火) 19:34 回答[未読]
【63853】Re:桁数が多いと勝手に指数で計算してうま... pon 09/12/22(火) 15:26 質問[未読]
【63854】Re:桁数が多いと勝手に指数で計算してうま... Yuki 09/12/22(火) 15:50 発言[未読]
【63855】Re:桁数が多いと勝手に指数で計算してうま... pon 09/12/22(火) 16:58 質問[未読]
【63856】Re:桁数が多いと勝手に指数で計算してうま... pon 09/12/22(火) 19:07 お礼[未読]
【63857】Re:桁数が多いと勝手に指数で計算してうま... ichinose 09/12/22(火) 22:09 発言[未読]
【63867】Re:桁数が多いと勝手に指数で計算してうま... よろずや 09/12/23(水) 23:45 発言[未読]
【63870】Re:桁数が多いと勝手に指数で計算してうま... pon 09/12/24(木) 18:36 お礼[未読]
【63868】Re:桁数が多いと勝手に指数で計算してうま... ichinose 09/12/24(木) 7:35 発言[未読]
【63871】Re:桁数が多いと勝手に指数で計算してうま... pon 09/12/24(木) 18:40 質問[未読]
【63874】Re:桁数が多いと勝手に指数で計算してうま... ichinose 09/12/25(金) 7:25 発言[未読]
【63880】Re:桁数が多いと勝手に指数で計算してうま... pon 09/12/25(金) 15:00 お礼[未読]
【63797】Re:桁数が多いと勝手に指数で計算してうま... ichinose 09/12/15(火) 21:58 発言[未読]
【63802】Re:桁数が多いと勝手に指数で計算してうま... Yuki 09/12/16(水) 13:33 発言[未読]
【63881】Re:桁数が多いと勝手に指数で計算してうま... pon 09/12/25(金) 15:01 お礼[未読]

【63725】桁数が多いと勝手に指数で計算してうまく...
質問  pon  - 09/12/3(木) 16:00 -

引用なし
パスワード
   よろしくお願いいたします


参照先の値は一方はセル値テキスト、もう一方は数式=TEXT(D21,"0000")&TEXT(D22,"0000")
のようにして作成しています

?myRange.Value2
35051000100001000000004000200000602

?CK_STR
35051000100001000100001000000000401

なんですが
If myRange.Value2 * 1 - CK_STR * 1 = 0 Then が 思いどうりに計算できません


?myRange.Value2 * 1 - CK_STR * 1
0

?myRange.Value2 * 1
3.5051000100001E+34

?CK_STR * 1
3.5051000100001E+34

となっていました


当初は
If myRange.Value2 = CK_STR Then
としていたが、うまく判定できずに上記のようにしてみましたがうまく出来ません


どうすればいいでしょうか
アドバイスよろしくお願いいたします

【63726】Re:桁数が多いと勝手に指数で計算してう...
発言  ichinose  - 09/12/3(木) 17:40 -

引用なし
パスワード
   こんばんは。

>If myRange.Value2 = CK_STR Then
>としていたが、うまく判定できずに上記のようにしてみましたがうまく出来ません

StrComp関数を調べてください。

【63787】Re:桁数が多いと勝手に指数で計算してう...
お礼  pon  - 09/12/15(火) 12:33 -

引用なし
パスワード
   大変遅くなりました

ご提示頂いた、StrCompで希望の操作はかないました
ichinose さん ありがとうございました


また、不具合の原因はエクセルの制限 有効桁数15桁 にあることがわかりました
Excel のセルに桁数の多い数字を入力すると最後の桁がゼロに変更される
://support.microsoft.com/kb/269370/ja

ただ、15桁超えを触りたいこともあるような気がして、時間が取れたときに
調査している間に遅くなってしまいました m(_ _)m


要は、
セル値においては15桁制限がありそれを超えて操作する場合は文字列として扱う
でした


下記によくわかりません

Q1
VBAでは通貨型ですれば扱えるような記載はwebではあったのですが
下記マクロでは15桁制限があるようです
コード中に記載

Q2
またb5-b11でセル表示が、右寄せ、左寄せの原因がわかりません

Q3
結構わずらわしそうな気がしますが
15桁以上数値扱いしたい場合は、15桁以下で分割処理で結合みたいな方法しかないのでしょうか
↑出来るかどうか いまいち自信がありませんが・・・


アドバイス有りましたらよろしくお願いいたします


テストコード
Sub cell_set()

  With Range("B1:B4")
    .NumberFormatLocal = "@"
    .Interior.ColorIndex = 6
  End With
  
  With Range("C1:C2")
    .NumberFormatLocal = "0_ "
    .Interior.ColorIndex = 8
  End With
  
  With Range("C3:C4")
    .NumberFormatLocal = "G/標準"
    .Interior.ColorIndex = 35
  End With
  
  
  Columns("A:C").ColumnWidth = 44
  
  
  'Dim d_int As Integer
  'Dim d_dbl As Double
  'Dim d_lng As Long
  'Dim d_cur As Currency
  
  'd_int = 3.5051000100001E+34
  'd_dbl = 3.5051000100001E+34
  'd_lng = 3.5051000100001E+34
  'd_cur = 3.5051000100001E+34
  '↑=35051000100001000100004000200000602等 としたが すべて勝手に = 3.5051000100001E+34 となった
  
  
  Cells(1, 1).Value = "V2_I173 35051000100001000100002000000000402"
  Cells(2, 1).Value = "V2_I173 35051000100001000100002000000000402"
  Cells(3, 1).Formula = 3.5051000100001E+34
  '↑=35051000100001000100004000200000602 としたが 勝手に = 3.5051000100001E+34 となった
  Cells(4, 1).Formula = "= 35051000100001000100002000000000402"
  
  Cells(1, 2).Value = "35051000100001000100002000000000402"
  Cells(2, 2).Value = "35051000100001000100002000000000402"
  Cells(3, 2).Value = "35051000100001000100004000200000602"
  Cells(4, 2).Value = "35051000100001000100004000200000602"
  
  Cells(1, 3).Value = "35051000100001000100002000000000402"
  Cells(2, 3).Value = "35051000100001000100002000000000402"
  Cells(3, 3).Formula = "35051000100001000100004000200000602"
  Cells(4, 3).Formula = "35051000100001000100004000200000602"
  
  Cells(5, 2).Formula = "= Mid(A1, Find("" "", A1) + 1, 100)"
  Cells(6, 2).Formula = "= Mid(A2, Find("" "", A2) + 1, 100) + 1"
  Cells(7, 2).Formula = "= B1"
  Cells(8, 2).Formula = "= B1 + 1"
  Cells(9, 2).Formula = "= text(B1 + 1,0)"
  Cells(10, 2).Formula = "= B1 * 1"
  Cells(11, 2).Formula = "=TEXT( B1 * 1,""#"")"
  
  Cells(15, 2).Formula = "=Text_StrComp(B1,B2)"
  Cells(16, 2).Formula = "=Text_StrComp(B1,B3)"
  Cells(17, 2).Formula = "=Text_StrComp(A3,A4)"
  
  
End Sub


Function Text_StrComp(tg1 As Range, tg2 As Range, Optional Opt As String)

  Text_StrComp = StrComp(tg1, tg2, vbTextCompare)

End Function

【63788】Re:桁数が多いと勝手に指数で計算してう...
質問  pon  - 09/12/15(火) 12:49 -

引用なし
パスワード
   追加の質問、
前投稿に記載しました
よろしくお願いいたします

【63789】Re:桁数が多いと勝手に指数で計算してう...
発言  Jaka  - 09/12/15(火) 13:42 -

引用なし
パスワード
   説明するのがへたっぴなので、うまくいえませんが。
表示形式が標準のセルに例え文字を入れたとしても、
勝手に数値に変換されてしまいます。

例えば、
Range("A20").Value = "1234567890"
右詰で数値変換されます。

この辺りをある程度理解しないと整理できないかも知れません。


セルの表示形式を文字列にして、文字として書き込む。

Range("A15").NumberFormatLocal = "@"
Range("A15").Value = "35051000100001000100004000200000602"

そのままでは、計算に使えません。
と言うより、SUM関数に使えないといったほうが良いか?
=A15+1 ←これは使えます、エクセルが勝手に数値変換して計算してくれるから。


おまけ、(Sum関数には使えません。)

Range("A16").NumberFormat = "General"
Dim st(1 To 1) As String
st(1) = "35051000100001000100004000200000602"
Range("A16").Value = st
MsgBox "A16をWクリックしたり、編集しようとしないでね。"

【63792】Re:桁数が多いと勝手に指数で計算してう...
質問  pon  - 09/12/15(火) 16:52 -

引用なし
パスワード
   ▼Jaka さん:

動作サンプルありがとうございます

>この辺りをある程度理解しないと整理できないかも知れません。
何気に奥の深いお言葉のような・・・・

エクセルのお節介機能でも
ツールオプション等で制御できるものから
>Range("A20").Value = "1234567890"
>右詰で数値変換されます。
はブラックボックス系お節介機能のような気がします

動作定義?が公開されているのかもしれませんが
ググッてみましたが見つかりませんでした。
過去1度も見たことが無いような気もしますので多分公開されていないような気がします

>この辺りをある程度理解しないと整理できないかも知れません。
はこんな理解でいいでしょうか?

【63794】Re:桁数が多いと勝手に指数で計算してう...
回答  よろずや  - 09/12/15(火) 19:34 -

引用なし
パスワード
   桁数の多い数値を扱うには、セルには文字列で格納します。
VBAで数値として扱うときは、十進型にします。
変数の定義に、十進型はありません。
Cdec関数で十進型に変換したものをVariant型変数に入れます。

【63797】Re:桁数が多いと勝手に指数で計算してう...
発言  ichinose  - 09/12/15(火) 21:58 -

引用なし
パスワード
   こんばんは。


>
>Q1
>VBAでは通貨型ですれば扱えるような記載はwebではあったのですが
>下記マクロでは15桁制限があるようです
Currencyだって、15桁程度ですよ!!

よろずやさんの記述のように10進型を使えば、桁数の多い数値を扱えます。

Sub sample1()
  Dim x As Variant
  x = CDec("1234567890123456789012345678")
  MsgBox x
  MsgBox x + 1
End Sub

でも、10進型を使っても28、29桁辺りが限界です。

35051000100001000100004000200000602

これを扱うのは、文字列として扱うしかないと思いますよ!!

大きい桁らの二つの数字の大小さえわかれば良いのなら、前投稿のように
文字列の数字をStrcomp関数を使って比較します。

'=======================================================
Sub test()
  MsgBox mystrcomp("3", "11")
  MsgBox mystrcomp("12333333333333333333333333333333333333333333333333333", "12333333333333333333333333333333333333333333333333333")
  MsgBox mystrcomp("35051000100001000100004000200000602", "35051000100001000100004000200000601")
End Sub
'======================================================================
Function mystrcomp(ByVal strnum1 As String, strnum2 As String) As Long
'  mystrcomp   1  strnum1>strnum2
'          0  strnum1=strnum2
'         -1  strnum1<strnum2
  
  Dim x As String
  Dim y As String
  x = Space(Application.Max(Len(strnum1), Len(strnum2)))
  y = x
  RSet x = strnum1
  RSet y = strnum2
  mystrcomp = StrComp(x, y)
End Function


>
>Q2
>またb5-b11でセル表示が、右寄せ、左寄せの原因がわかりません

これは、意味がわかりません


>Q3
>結構わずらわしそうな気がしますが
>15桁以上数値扱いしたい場合は、15桁以下で分割処理で結合みたいな方法しかないのでしょうか

すべての数値を文字列化して、比較することはStrcompを使えばできますよ!!


大きい桁(35桁程度)の演算がしたいなら、
足し算や引き算をVBAでシュミレートしなければなりませんねえ。

【63802】Re:桁数が多いと勝手に指数で計算してう...
発言  Yuki  - 09/12/16(水) 13:33 -

引用なし
パスワード
   ▼pon さん:
こんにちは。
回答では有りません。
>
>また、不具合の原因はエクセルの制限 有効桁数15桁 にあることがわかりました

電卓を使えば有効桁数32桁まで計算できるようです。
マクロで電卓を起動して数値、演算子、数値で結果を取出す。
位は出来そうです。

【63853】Re:桁数が多いと勝手に指数で計算してう...
質問  pon  - 09/12/22(火) 15:26 -

引用なし
パスワード
   大変遅くなりました m(_ _)m
皆様アドバイスありがとうございます


To よろずや さん

>変数の定義に、十進型はありません。
なるほどです
言われて理解が深まりました

>桁数の多い数値を扱うには、セルには文字列で格納します。
>VBAで数値として扱うときは、十進型にします。
>Cdec関数で十進型に変換したものをVariant型変数に入れます。

作業手順ありがとうございます
勉強になりました


To ichinose さん
>でも、10進型を使っても28、29桁辺りが限界です。
ありがとうございます

データ型変換関数
tp://msdn.microsoft.com/ja-jp/library/s2dy91zy%28VS.80%29.aspx
CDec 10 進型 (Decimal) (Visual Basic)
小数点以下が 0 桁 (小数部分を持たない数値) の場合、-79,228,162,514,264,337,593,543,950,335 〜 79,228,162,514,264,337,593,543,950,335。
ありました

x = CDec("123456789012345678901234567890")

実行時エラー '6':
オーバーフローしました。
で、快感でなく 実感できました (^_^;;;

mystrcomp
ありがとうございました

>>Q2
>>またb5-b11でセル表示が、右寄せ、左寄せの原因がわかりません

>これは、意味がわかりません

ですが(B12追加しました)
B6  右寄せ    3.5051E+34    '= MID(A2, FIND(" ", A2) + 1, 100) + 1
B7  左寄せ    35051000100001000100002000000000402    '= B1
B8  左寄せ    3.5051E+34    '= B1 + 1
B9  左寄せ    35051000100001000000000000000000000    '= TEXT(B1 + 1,0)
B10  右寄せ    3.5051E+34    '= B1 * 1
B11  左寄せ    35051000100001000000000000000000000    '=TEXT( B1 * 1,"#")
B12  左寄せ 追加    35051000100001000100002000000000402    '= MID(A2, FIND(" ", A2) + 1, 100)

B6が右寄せ、B12が左寄せ
B8が指数で左寄せ
B7が左寄せ、B10が右寄せ
となる理由がわかりません
何か有りましたらよろしくお願い致します

>すべての数値を文字列化して、比較することはStrcompを使えばできますよ!!
了解です

>大きい桁(35桁程度)の演算がしたいなら、
>足し算や引き算をVBAでシュミレートしなければなりませんねえ。
ありがとうございます
この辺もう少し勉強してみたいと思います


To Yuki さん
>電卓を使えば有効桁数32桁まで計算できるようです。
>マクロで電卓を起動して数値、演算子、数値で結果を取出す。
>位は出来そうです。
ありがとうございます
ただ、APIでウインドウを捕獲しないと駄目そうなので
ちょっと敷居が高そうです
時間をとってチャレンジしてみたいと思います


いまいち理解出来ていないのですが
>大きい桁(35桁程度)の演算がしたいなら、
>足し算や引き算をVBAでシュミレートしなければなりませんねえ。
は文字列操作ではなく値操作と思うのですが
上記の
データ型変換関数
tp://msdn.microsoft.com/ja-jp/library/s2dy91zy%28VS.80%29.aspx
の一覧表では最高桁数 CDec の 29桁 です

>電卓を使えば有効桁数32桁まで計算できるようです。
はどのようにしておこなっているのでしょうか


また、やはり数値あつかいでは35桁の取り扱いはVBAでも出来ないのでしょうか


色々いたキーワードで再度調べてみたのですが
初級シスアドのIEEE754あたりでは基本事項のような感じでした
上記の勉強などしたこともなく基本的な知識の欠如を痛感しています

この辺の理解が必要な気もしてきましたがどうなんでしょう
頓珍漢なことを考えているような気もします

アドバイス有りましたらよろしくお願い致します

【63854】Re:桁数が多いと勝手に指数で計算してう...
発言  Yuki  - 09/12/22(火) 15:50 -

引用なし
パスワード
   ▼pon さん:
試してみて下さい。

Option Explicit
Private Declare Function FindWindow Lib "user32.dll" _
             Alias "FindWindowA" _
            (ByVal lpClassName As String, _
             ByVal lpWindowName As String) As Long

Private Declare Function FindWindowEx Lib "user32.dll" _
             Alias "FindWindowExA" _
            (ByVal hwndParent As Long, _
             ByVal hwndChildAfter As Long, _
             ByVal lpszClass As String, _
             ByVal lpszWindow As String) As Long
  
Private Const WM_COMMAND = &H111
Private Const WM_CLOSE = &H10
Private Const WM_SETTEXT = &HC
Private Const WM_GETTEXT = &HD
Private Const WM_GETTEXTLENGTH = &HE
Private Const BN_CLICKED = 0
Private Const BM_CLICK = &HF5&

Private Declare Function PostMessage Lib "User32" _
             Alias "PostMessageA" _
            (ByVal hWnd As Long, _
             ByVal Msg As Long, _
             ByVal wParam As Long, _
             ByVal lParam As Long) As Long

Declare Function SendMessage Lib "user32.dll" _
             Alias "SendMessageA" _
            (ByVal hWnd As Long, _
             ByVal Msg As Long, _
             ByVal wParam As Long, _
             lParam As Any) As Long

Private Declare Function SendDlgItemMessageA Lib "User32" _
            (ByVal hDlg As Long, _
             ByVal nIDDlgItem As Long, _
             ByVal Msg As Long, _
             ByRef wParam As Any, _
             ByRef lParam As Any) As Long
  
Private Const HWND_TOPMOST As Long = -1&
Private Const SWP_NOSIZE  As Long = &H1&
Private Const SWP_NOMOVE  As Long = &H2&

Private Declare Function SetWindowPos Lib "User32" _
            (ByVal hWnd As Long, _
             ByVal hWndInsertAfter As Long, _
             ByVal x As Long, _
             ByVal y As Long, _
             ByVal cx As Long, _
             ByVal cy As Long, _
             ByVal wFlags As Long) As Long
  
Private hWnd    As Long ' hWnd
Private hEditWnd  As Long ' Edit
Private Const dBtn As Long = &H5A&  '/  5A
Private Const xBtn As Long = &H5B&  '*  5B
Private Const aBtn As Long = &H5C&  '+  5C
Private Const sBtn As Long = &H5D&  '-  5D
Private Const eBtn As Long = &H70&  '=  70
Private Const cBtn As Long = &H51&  'C  51

Private dHwnd As Long  '/
Private xHwnd As Long  '*
Private aHwnd As Long  '+
Private sHwnd As Long  '-
Private eHwnd As Long  '=
Private tHwnd As Long

Private Const btn0 As Long = &H7C&
Private Const btn1 As Long = &H7D&
Private Const btn2 As Long = &H7E&
Private Const btn3 As Long = &H7F&
Private Const btn4 As Long = &H80&
Private Const btn5 As Long = &H81&
Private Const btn6 As Long = &H82&
Private Const btn7 As Long = &H83&
Private Const btn8 As Long = &H84&
Private Const btn9 As Long = &H85&

Private hWnd0 As Long
Private hWnd1 As Long
Private hWnd2 As Long
Private hWnd3 As Long
Private hWnd4 As Long
Private hWnd5 As Long
Private hWnd6 As Long
Private hWnd7 As Long
Private hWnd8 As Long
Private hWnd9 As Long

' 電卓の起動
Sub CalucStart()
  Dim lngRtn As Long
  Dim strA  As String
  ' 電卓
  Application.ActivateMicrosoftApp Index:=0
  ' 電卓の hWnd
  hWnd = FindWindowEx(0&, 0&, "SciCalc", "電卓")
  ' 最前面に表示
  SetWindowPos hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE Or SWP_NOMOVE
End Sub

Function CalucProc(str1 As String, str2 As String, pType As String) As String
  Dim lngRtn As Long
  Dim ary1  As Variant
  Dim ary2  As Variant
  Dim i    As Long
  Dim mType  As Long
  Dim strBuff As String * 255
  
  If Not (IsNumeric(str1) And IsNumeric(str2)) Then
    MsgBox "数値が入力されていません。"
    Exit Function
  End If
  
  ' 電卓の hWnd
  hWnd = FindWindowEx(0&, 0&, "SciCalc", "電卓")
  If hWnd = 0 Then Call CalucStart
'  [関数電卓]のメニューID = 304
  lngRtn = PostMessage(hWnd, WM_COMMAND, 304, 0)
'  電卓内のEdit Handle
  hEditWnd = FindWindowEx(hWnd, 0&, "Edit", vbNullString)
  '十進数
  tHwnd = FindWindowEx(hWnd, 0&, "Button", "10 進")
  lngRtn = SendMessage(tHwnd, BM_CLICK, ByVal 0&, ByVal 0&)
  'Clear
  SendDlgItemMessageA hWnd, cBtn, BM_CLICK, ByVal 0&, ByVal 0&
  
  dHwnd = FindWindowEx(hWnd, 0&, "Button", "/")
  xHwnd = FindWindowEx(hWnd, 0&, "Button", "*")
  aHwnd = FindWindowEx(hWnd, 0&, "Button", "+")
  sHwnd = FindWindowEx(hWnd, 0&, "Button", "-")
  eHwnd = FindWindowEx(hWnd, 0&, "Button", "=")
  
  hWnd0 = FindWindowEx(hWnd, 0&, "Button", "0")
  hWnd1 = FindWindowEx(hWnd, 0&, "Button", "1")
  hWnd2 = FindWindowEx(hWnd, 0&, "Button", "2")
  hWnd3 = FindWindowEx(hWnd, 0&, "Button", "3")
  hWnd4 = FindWindowEx(hWnd, 0&, "Button", "4")
  hWnd5 = FindWindowEx(hWnd, 0&, "Button", "5")
  hWnd6 = FindWindowEx(hWnd, 0&, "Button", "6")
  hWnd7 = FindWindowEx(hWnd, 0&, "Button", "7")
  hWnd8 = FindWindowEx(hWnd, 0&, "Button", "8")
  hWnd9 = FindWindowEx(hWnd, 0&, "Button", "9")
  
  ary1 = Array(hWnd0, hWnd1, hWnd2, hWnd3, hWnd4, hWnd5, hWnd6, hWnd7, hWnd8, hWnd9)
  ary2 = Array(btn0, btn1, btn2, btn3, btn4, btn5, btn6, btn7, btn8, btn9)
  
  Select Case pType
    Case "*", "X"
      mType = xHwnd
    Case "/"
      mType = dHwnd
    Case "+"
      mType = aHwnd
    Case "-"
      mType = sHwnd
    Case Else
      mType = 0
  End Select
  If mType = 0 Then Exit Function
  
  ' 1 数字のSet
  For i = 1 To Len(str1)
    lngRtn = SendMessage(ary1(Mid(str1, i, 1)), BM_CLICK, ByVal 0&, ByVal 0&)
  Next
  ' 四則演算子
  lngRtn = SendMessage(mType, BM_CLICK, ByVal 0&, ByVal 0&)
  ' 2 数字のSet
  For i = 1 To Len(str2)
    lngRtn = SendMessage(ary1(Mid(str2, i, 1)), BM_CLICK, ByVal 0&, ByVal 0&)
  Next
  lngRtn = SendMessage(eHwnd, BM_CLICK, ByVal 0&, ByVal 0&)
  lngRtn = SendMessage(hEditWnd, WM_GETTEXT, Len(strBuff), ByVal strBuff)
  ' 結果表示
  CalucProc = Left(strBuff, InStr(strBuff, vbNullChar) - 1)
End Function

Sub MainProc()
  Dim s1 As String
  Dim s2 As String
  ' 32桁 その後は指数
  s1 = "35051000100001000100002000004021"
  s2 = "35051000100001000100002000004022"
  '結果表示
  Debug.Print Trim(CalucProc(s1, s2, "+"))
End Sub

電卓の起動 CalucStart を実行したあとに

MainProcを実行してみて下さい。
第1第2引数は計算値で第3引数は演算子です。
乗算は X or * 除算は / 加算は + 減算は - です。
結果はイミディエイトウィンドウにでます。

【63855】Re:桁数が多いと勝手に指数で計算してう...
質問  pon  - 09/12/22(火) 16:58 -

引用なし
パスワード
   ▼Yuki さん:
ありがとうございます


>ただ、APIでウインドウを捕獲しないと駄目そうなので
>ちょっと敷居が高そうです
>時間をとってチャレンジしてみたいと思います

敷居が高いどころか手も足もでないコードでした
コードのご提示ありがとうございました

? Trim(CalucProc( "50000000000000000000000000000000", "2", "*"))
1.e+32
? Trim(CalucProc( "49999999999999999999999999999999", "2", "*"))
99999999999999999999999999999998.

で、32桁が実感できました

こんな数値取り扱うことは無いようなです

>ご提示頂いた、StrCompで希望の操作はかないました
です

無用なことに気を回しすぎたです (~_~;)

32桁での計算はどの辺の業界で使用するのか逆に気になってしまいます  (^_^;;;


ちなみに 日本の数詞   
tp://www004.upp.so-net.ne.jp/s_honma/numeral.htm
なんてありました
ちょっとびっくりでした


こちら
pon  - 09/12/22(火) 15:26
>>Q2
>>またb5-b11でセル表示が、右寄せ、左寄せの原因がわかりません
コメント有りましたらよろしくお願い致します

【63856】Re:桁数が多いと勝手に指数で計算してう...
お礼  pon  - 09/12/22(火) 19:07 -

引用なし
パスワード
   ▼Yuki さん:
追記です

API憧れです

少しづつでも身に着けたいと思っています
勉強させて頂きます

ありがとうございました

【63857】Re:桁数が多いと勝手に指数で計算してう...
発言  ichinose  - 09/12/22(火) 22:09 -

引用なし
パスワード
   こんばんは。

>ですが(B12追加しました)
>B6  右寄せ    3.5051E+34    '= MID(A2, FIND(" ", A2) + 1, 100) + 1
>B7  左寄せ    35051000100001000100002000000000402    '= B1
>B8  左寄せ    3.5051E+34    '= B1 + 1
>B9  左寄せ    35051000100001000000000000000000000    '= TEXT(B1 + 1,0)
>B10  右寄せ    3.5051E+34    '= B1 * 1
>B11  左寄せ    35051000100001000000000000000000000    '=TEXT( B1 * 1,"#")
>B12  左寄せ 追加    35051000100001000100002000000000402    '= MID(A2, FIND(" ", A2) + 1, 100)
>で
>B6が右寄せ、B12が左寄せ
B6は、最後に +1 で算術演算とみなされます。よって、数値が返り、右寄せ
B12は、文字列の編集なので左寄せ

>B8が指数で左寄せ
これは、??? B1は、文字列ですよね?
(再現できないので、さらに再現手順を詳細に記述してください)

>B7が左寄せ、B10が右寄せ
B7は、文字列編集だから左寄せ
B10は、算術演算だから、右寄せ


>>大きい桁(35桁程度)の演算がしたいなら、
>>足し算や引き算をVBAでシュミレートしなければなりませんねえ。

>は文字列操作ではなく値操作と思うのですが
これは、昔やった縦書きの足し算(加法の場合)をVBAでコード化するのですよ

123
29 +
--------


3+9で 2で1繰り上がって・・・・  ってやつ
結果はあくまで文字列でだすのですよ!!そうしないと表現できないので・・・。

標準モジュールに


Option Explicit
'================================================================
Sub test()
  Dim s1 As String
  Dim s2 As String
  s1 = "123"
  s2 = "29"
  [a1].Value = "'" & stradd(s1, s2)
  s1 = "3505100010000100010000200000402111111111"
  s2 = "35"
  [a2].Value = "'" & stradd(s1, s2)
End Sub
'=================================================================
Function stradd(ByVal str1 As String, str2 As String) As String
  Dim l1 As Long
  Dim l2 As Long
  Dim g0 As Long
  Dim g1 As Long
  Dim g2 As Long
  Dim g3 As Long
  l1 = Len(str1)
  l2 = Len(str2)
  g3 = 0
  Do While l1 > 0 Or l2 > 0
    If l1 > 0 Then g1 = Val(Mid(str1, l1, 1)) Else g1 = 0
    If l2 > 0 Then g2 = Val(Mid(str2, l2, 1)) Else g2 = 0
    g0 = g1 + g2 + g3
    g3 = g0 \ 10
    stradd = CStr((g0 Mod 10)) & stradd
    l1 = l1 - 1
    l2 = l2 - 1
  Loop
  If g3 > 0 Then stradd = CStr(g3) & stradd
End Function


これは、足し算ですが、引き算も掛け算も考え方は同じです。

そういや、何年か前の今頃だったなあ、
平方根を100桁(もっとだったかなあ)ぐらい計算したい
なんていうご質問があったなあ・・・。
その時も平方根の計算をシュミレートすれば という投稿を
したと思いました。

【63867】Re:桁数が多いと勝手に指数で計算してう...
発言  よろずや  - 09/12/23(水) 23:45 -

引用なし
パスワード
   VBAで多倍長演算を行うためのライブラリ
なんて検索するといろいろ出てきますね。

【63868】Re:桁数が多いと勝手に指数で計算してう...
発言  ichinose  - 09/12/24(木) 7:35 -

引用なし
パスワード
   おはようございます。

ついでに引き算

'===================================================================
Sub test2()
  Dim s1 As String
  Dim s2 As String
  s1 = "131"
  s2 = "125"
  [a1].Value = "'" & strsub(s1, s2)
  s1 = "3505100010000100010000200000402111111111"
  s2 = "35"
  [a2].Value = "'" & strsub(s1, s2)
End Sub
'=================================================================
Function strsub(ByVal str1 As String,ByVal str2 As String) As String
  Dim l1 As Long
  Dim l2 As Long
  Dim g0 As Long
  Dim g1 As Long
  Dim g2 As Long
  Dim g3 As Long
  Dim wk As String
  Dim hugo As String
  g0 = mystrcomp(str1, str2)
  hugo = ""
  If g0 = -1 Then
    wk = str1
    str1 = str2
    str2 = wk
    hugo = "-"
  End If
  If g0 = 0 Then
    strsub = "0"
  Else
    l1 = Len(str1)
    l2 = Len(str2)
    g3 = 0
    Do While l1 > 0 Or l2 > 0
     If l1 > 0 Then g1 = Val(Mid(str1, l1, 1)) Else g1 = 0
     If l2 > 0 Then g2 = Val(Mid(str2, l2, 1)) Else g2 = 0
     g0 = g1 - g2 - g3
     If g0 < 0 Then
       g0 = 10 + g0
       g3 = 1
     Else
       g3 = 0
     End If
     strsub = CStr(g0) & strsub
     l1 = l1 - 1
     l2 = l2 - 1
    Loop
    For g0 = 1 To Len(strsub)
     If Mid(strsub, g0, 1) <> "0" Then
       strsub = Mid(strsub, g0)
       Exit For
     End If
    Next
    strsub = hugo & strsub
  End If
End Function
'=======================================================================
Function mystrcomp(ByVal strnum1 As String,ByVal strnum2 As String) As Long
'  mystrcomp   1  strnum1>strnum2
'          0  strnum1=strnum2
'         -1  strnum1<strnum2
 
  Dim x As String
  Dim y As String
  x = Space(Application.Max(Len(strnum1), Len(strnum2)))
  y = x
  RSet x = strnum1
  RSet y = strnum2
  mystrcomp = StrComp(x, y)
End Function

【63870】Re:桁数が多いと勝手に指数で計算してう...
お礼  pon  - 09/12/24(木) 18:36 -

引用なし
パスワード
   ▼よろずや さん:
ありがとうございます

>VBAで多倍長演算を行うためのライブラリ
>なんて検索するといろいろ出てきますね。

VBAで多倍長演算を行うためのライブラリ と サンプルプログラム
tp://www.geocities.jp/kamegai2006/html/soft.htm#BigInt

ダウンロードしてみました
コード公開されているのですが、ライブラリって作りこみがすごいですね・・・
理解できるかわかりませんが勉強してみたいと思います

とりあえずのご報告でした

【63871】Re:桁数が多いと勝手に指数で計算してう...
質問  pon  - 09/12/24(木) 18:40 -

引用なし
パスワード
   ▼ichinose さん:
ありがとうございます

>>Q2
で解説いただいた内容は

Mid 関数
文字列から指定した文字数分の文字列を返します。
を踏まえて
値      右
文字列    左
MIDで文字列    左
'+で数値      右
'&で文字    左
は了解ですが下記わかりません

= は参照先が数値なら 右 、文字列なら 左
でした
いまさらながらですが、動作としてわかりましたが
この動作のhelpみたいなものはあるのでしょうか
調べてみましたが見つかりませんでした
単純一般機能として理解すればいいような気もしますが・・・・


>>B8が指数で左寄せ
>これは、??? B1は、文字列ですよね?
>(再現できないので、さらに再現手順を詳細に記述してください)
ですが
下記で再現できます
C4が指数表示で右寄せ
C7が指数表示なのに左寄せとなっています
ただ 参照先が 
C4は、MID関数式
C7は、等号式?
の違いがありますが・・・・・
何か有りましたらよろしくお願い致します


Sub cell_set2()
  
  Cells.Delete Shift:=xlUp
  
  Range("B2").Value = "V2_I173 35051000100001000100002000000000402"
  
  Range("C2").Formula = "= MID(B2, FIND("" "", B2)+1, 100)"
  Range("C3").Formula = "=C2"
  Range("C4").Formula = "=C2+1"
  
  Range("B6").NumberFormatLocal = "@"
  Range("B6").Value = "35051000100001000100002000000000402"
  
  Range("C6").Formula = "=B6"
  Range("C7").Formula = "=B6+1"
  
  Columns("B:C").EntireColumn.AutoFit

  Range("B2").Select
  
End Sub


足し算 引き算 の コード ありがとうございます
>これは、昔やった縦書きの足し算(加法の場合)をVBAでコード化するのですよ

やっと文字列操作の方法がイメージがつかめましたが
ムム〜 このタイプのコードなんでか苦手で自力ではかけません 
作成し始めるといつも何をしているか迷子になってギブアップみたいな・・
何でなんでしょ
一応動作はわかるのですが・・多分自力では書けない・・
フローチャート?が書けるようになればいいのかな?
(自慢ではありませんが書いたことはありません)
アホだからでもいいですが、何かアドバイス頂けると一歩進めるような気がします
なにかありましたらよろしくお願いします

後、
足し算の If g3 > 0 Then
の意味が下記で確認してもなぜいるのかよくわからないのですが・・・
アドバイス頂けるとうれしいです
よろしくお願いいたします


>その時も平方根の計算をシュミレートすれば という投稿を
>したと思いました
▼【32873】マクロで平方根を・・・・・
tp://www.vbalab.net/vbaqa/c-board.cgi?cmd=ntr;tree=32873;id=excel
ありがとうございます
別途勉強させて頂きます


初心者さんの場合は同じような人がいるかもしれませんので
一応下記書いてみました
頂いたコードを下記のようにしてステップ実行すると動作だけはわかると思います

足し算
Option Explicit
'================================================================
Sub test()
  Dim s1 As String
  Dim s2 As String
  s1 = "123"
  s2 = "29"
  [a1].Value = "'" & stradd(s1, s2)
  s1 = "3505100010000100010000200000402111111111"
  s2 = "35"
  [a2].Value = "'" & stradd(s1, s2)
End Sub
'=================================================================
Function stradd(ByVal str1 As String, str2 As String) As String
  Dim l1 As Long
  Dim l2 As Long
  Dim g0 As Long
  Dim g1 As Long
  Dim g2 As Long
  Dim g3 As Long
  l1 = Len(str1)
  l2 = Len(str2)
  g3 = 0
  Do While l1 > 0 Or l2 > 0
    If l1 > 0 Then g1 = Val(Mid(str1, l1, 1)) Else g1 = 0
    If l2 > 0 Then g2 = Val(Mid(str2, l2, 1)) Else g2 = 0
    g0 = g1 + g2 + g3
    g3 = g0 \ 10
    stradd = CStr((g0 Mod 10)) & stradd
    l1 = l1 - 1
    l2 = l2 - 1
   
    Debug.Print stradd  'ブレークポイントセット
   
  Loop
  
  If g3 > 0 Then  'ブレークポイントセット
    
    Debug.Print
    Debug.Print CStr(g3)
    Debug.Print stradd

    stradd = CStr(g3) & stradd
    
  Else  'ブレークポイントセット
  
    Debug.Print
    Debug.Print CStr(g3)
    Debug.Print stradd
    
  End If
  
End Function


引き算
Option Explicit

'===================================================================
Sub test2()
  Dim s1 As String
  Dim s2 As String
  s1 = "131"
  s2 = "145"
  [a1].Value = "'" & strsub(s1, s2)
  s1 = "3505100010000100010000200000402111111111"
  s2 = "35"
  [a2].Value = "'" & strsub(s1, s2)
End Sub
'=================================================================
Function strsub(ByVal str1 As String, ByVal str2 As String) As String
  Dim l1 As Long
  Dim l2 As Long
  Dim g0 As Long
  Dim g1 As Long
  Dim g2 As Long
  Dim g3 As Long
  Dim wk As String
  Dim hugo As String
  g0 = mystrcomp(str1, str2)
  hugo = ""
  If g0 = -1 Then
    wk = str1
    str1 = str2
    str2 = wk
    hugo = "-"
  End If
  If g0 = 0 Then
    strsub = "0"
  Else
    l1 = Len(str1)
    l2 = Len(str2)
    g3 = 0
    Do While l1 > 0 Or l2 > 0
     If l1 > 0 Then g1 = Val(Mid(str1, l1, 1)) Else g1 = 0
     If l2 > 0 Then g2 = Val(Mid(str2, l2, 1)) Else g2 = 0
     g0 = g1 - g2 - g3
     If g0 < 0 Then
       g0 = 10 + g0
       g3 = 1
     Else
       g3 = 0
     End If
     strsub = CStr(g0) & strsub
     l1 = l1 - 1
     l2 = l2 - 1
     
     Debug.Print strsub  'ブレークポイントセット
     
    Loop
   
    Debug.Print
   
    For g0 = 1 To Len(strsub)
     
     Debug.Print Mid(strsub, g0, 1)
   
     If Mid(strsub, g0, 1) <> "0" Then
       strsub = Mid(strsub, g0)
       Exit For
     End If
    Next
    strsub = hugo & strsub
   
    Debug.Print
    Debug.Print strsub  'ブレークポイントセット (str2>str1でも試す)
   
  End If
End Function
'=======================================================================
Function mystrcomp(ByVal strnum1 As String, ByVal strnum2 As String) As Long
'  mystrcomp   1  strnum1>strnum2
'          0  strnum1=strnum2
'         -1  strnum1<strnum2

  Dim x As String
  Dim y As String
  x = Space(Application.Max(Len(strnum1), Len(strnum2)))
  y = x
  Rset x = strnum1
  Rset y = strnum2
  mystrcomp = StrComp(x, y)
End Function

【63874】Re:桁数が多いと勝手に指数で計算してう...
発言  ichinose  - 09/12/25(金) 7:25 -

引用なし
パスワード
   おはようございます。
現象確認しました。


>いまさらながらですが、動作としてわかりましたが
>この動作のhelpみたいなものはあるのでしょうか
解説サイトの紹介は他の方に任せますが・・・、
仕様だと思っていたのでまったく疑問に思わなかったなあ・・・。


>>下記で再現できます
>C4が指数表示で右寄せ
>C7が指数表示なのに左寄せとなっています
>ただ 参照先が 
>C4は、MID関数式
>C7は、等号式?
>の違いがありますが・・・・・
現象確認しました。
投稿されたコードを実行しました。
セルC7の書式が「文字列」に変わっていますね?
結果が左寄せになるのは、↑これが起因していそうですが・・。
投稿されたプロシジャーのコード順序を以下のようにすると、セルC7は、右寄せになりますね!!

Sub cell_set2()
  Cells.Delete Shift:=xlUp
  Range("B2").Value = "V2_I173 35051000100001000100002000000000402"
  Range("C2").Formula = "= MID(B2, FIND("" "", B2)+1, 100)"
  Range("C3").Formula = "=C2"
  Range("C4").Formula = "=C2+1"
  Range("C6").Formula = "=B6"
  Range("C7").Formula = "=B6+1"
  Range("B6").NumberFormatLocal = "@"
  Range("B6").Value = "35051000100001000100002000000000402"
  Columns("B:C").EntireColumn.AutoFit
  Range("B2").Select
End Sub


>アホだからでもいいですが、何かアドバイス頂けると一歩進めるような気がします
>なにかありましたらよろしくお願いします

足し算を例にとれば、

桁の小さい数字から桁をあわせて順々に足し算していって、桁が繰り上がったら、
次の桁に1を繰り越す という処理を数字があるだけ繰り返す

という処理です。

123
 89+
-----------
  

3+9=12 で 1の位は 2で 1が繰り上がって・・、
2+8+1(繰り上がり)=11で10の位は、1で1繰り上がって
1+1(繰り上がり)=2で 繰り上がりはなし

結果 212 という答えが得られます。

こんな過程から、ロジックとして、繰り返す処理(Do〜Loopの中で処理する内容)を
検討します。

私は、

プログラムの基本形式のひとつである

 前処理
  |
  |
 1回以上のループ
  |
  |
 後処理

という形式にすることを考えてプログラムの作成にあたっています。
(ワーニエ法より)

>後、
>足し算の If g3 > 0 Then
>の意味が下記で確認してもなぜいるのかよくわからないのですが・・・
>アドバイス頂けるとうれしいです
>よろしくお願いいたします

これは、最後の桁の足し算で繰り上げがあったときの処理です。

Sub test2()
  MsgBox stradd("99", "1")
End Sub

上記は、100 と表示されますが、

If g3 > 0 Then 〜

がないと、00と表示されてしまいます。


以上です。

【63880】Re:桁数が多いと勝手に指数で計算してう...
お礼  pon  - 09/12/25(金) 15:00 -

引用なし
パスワード
   ▼ichinose さん:
ありがとうございます


>>いまさらながらですが、動作としてわかりましたが
>>この動作のhelpみたいなものはあるのでしょうか
>解説サイトの紹介は他の方に任せますが・・・、
>仕様だと思っていたのでまったく疑問に思わなかったなあ・・・。
そうですね
仕様と思えばいいと思います


>現象確認しました。
>投稿されたコードを実行しました。
>セルC7の書式が「文字列」に変わっていますね?
ほんとだ
右寄せ、左寄せぐらいの確認のみで
文字列かどうか確認していませんでした

>投稿されたプロシジャーのコード順序を以下のようにすると、セルC7は、右寄せになりますね!!
ムム 面白いというか??です
仕様(バグ)みたいですね
検証ありがとうございました


>足し算を例にとれば、
詳細な解説ありがとうございました
ご提示の方法勉強したいと思います

ワーニエ法 はじめて聞きました
この辺もあわせて勉強したいと思います


>これは、最後の桁の足し算で繰り上げがあったときの処理です。
勉強になります
色々ご教授ありがとうございました

【63881】Re:桁数が多いと勝手に指数で計算してう...
お礼  pon  - 09/12/25(金) 15:01 -

引用なし
パスワード
   皆様 色々ご教授ありがとうございました
今後もよろしくお願いいたします


解決です

3153 / 13644 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free