Excel VBA質問箱 IV

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

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


248 / 3841 ページ ←次へ | 前へ→

【77494】Re:タイで実行するとエラーになります
お礼  とし  - 15/10/16(金) 16:12 -

引用なし
パスワード
   お世話になります。

ウッシさん。回答ありがとうございます。

> エラーになった時の strFileName_Write を Debug.Print で取得しておいて、
> 新しいExcelでそのパスで名前を付けて保存する作業をマクロに記録して
> みてはどうですか?

  →タイに依頼してみます。ありがとうございます。
・ツリー全体表示

【77493】Re:数値がプラスマイナスのとき、データ...
お礼  みか  - 15/10/16(金) 16:10 -

引用なし
パスワード
   β さん、たびたびありがとうございます。
分かりやすく、纏まった構文ですね。
私が作ったものとは大違い、、、

いつかβさんのようなプログラムが作れるように頑張ります。
本当にありがとうございました。
・ツリー全体表示

【77492】Re:タイで実行するとエラーになります
回答  ウッシ  - 15/10/16(金) 15:57 -

引用なし
パスワード
   コントロールパネル → 時計、言語、および地域 → 地域と言語で開く
ダイアログの管理タブの下側にある
「Unicode 対応ではないプログラムの言語」は日本語になっていますか?

という文章をネットで見つけました。
一応確認してみてはどうですか?
・ツリー全体表示

【77491】Re:タイで実行するとエラーになります
回答  ウッシ  - 15/10/16(金) 15:54 -

引用なし
パスワード
   こんにちは

エラーになった時の strFileName_Write を Debug.Print で取得しておいて、
新しいExcelでそのパスで名前を付けて保存する作業をマクロに記録して
みてはどうですか?

うまく保存出来ればそのコードが参考になると思います。
・ツリー全体表示

【77490】Re:タイで実行するとエラーになります
発言  とし  - 15/10/16(金) 15:47 -

引用なし
パスワード
   お世話になります。

ウッシさん。回答ありがとうございます。

> 英語版なら、コメントやファイル名にも日本語は使わない方がいいですよね。

  →そこは意識して、日本語を使用しないようにしておりますが
   コメントもダメだったんですね、認識いたしました。

  →コメントはほぼ全部日本語なのですが
   半角英数字等に修正すべきでしょうか。


> 変数または定数「gFormat」には何がセットされていますか?

  →使っているエクセルのバージョンにより異なる数値をセットしております。

  (1)97-2003の場合、    「gFormat」に「-4143」をセット
  (2)2007-2010の場合の場合、「gFormat」に「51」  をセット

   ※ネット上に掲載されている情報を参考にしました。


> エラーになる時の「strFileName_Write」はどのような内容ですか?

  'ブック名を設定する(元エクセルファイル名_年月日_Buyer Department Code)
  strFileName_Write = strFileName_Left & "_" & Format(Date, "yyyymmdd") & "_" & strBuyer_Department_Code & strFileName_Right

  →下記のような値が設定されており、それぞれを合体させています。

   strFileName_Left    :インプットファイル名(フルパス付)のピリオドより左側
   strBuyer_Department_Code:インプットファイル内に存在するバイヤー部門コード
   strFileName_Right    :エクセルのバージョンに応じた拡張子

   ※インプットファイルの中身を確認しましたが、バイヤー部門コードは半角文字(英数字の羅列)でした。
・ツリー全体表示

【77489】Re:数値がプラスマイナスのとき、データ...
発言  β  - 15/10/16(金) 14:00 -

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

それはよかったです。

一応書きましたので参考まで。

Sub Test2()
  Dim v As Variant
  Dim x As Long
  Dim y As Long
  Dim r As Range
  
  With Range("X1", Range("X" & Rows.Count).End(xlUp)).Resize(, 3)
    ReDim v(1 To .Rows.Count)
    For Each r In .Rows
      x = x + 1
      v(x) = getDim(r)
    Next
  End With
  
  Columns("X:Z").ClearContents
  y = 1
  
  For x = 1 To UBound(v)
    Cells(y, "X").Resize(UBound(v(x), 1), 3).Value = v(x)
    y = Range("X" & Rows.Count).End(xlUp).Row + 1
  Next
  
End Sub

Private Function getDim(r As Range) As Variant
  Dim wX As Variant
  Dim wY As Variant
  Dim wZ As Variant
  Dim dX As Variant
  Dim dY As Variant
  Dim dZ As Variant
  Dim v As Variant
  Dim n As Variant
  Dim x As Long
 
  ReDim v(1 To 2 * 2 * 2, 1 To 3)
  
  n = r.Cells(1, 1).Value
  If Left(n, 1) = "±" Then
    ReDim wX(1 To 2)
    wX(1) = Mid(n, 2)
    wX(2) = Mid(n, 2) * -1
  Else
    ReDim wX(1 To 1)
    wX(1) = n
  End If
 
  n = r.Cells(1, 2).Value
  If Left(n, 1) = "±" Then
    ReDim wY(1 To 2)
    wY(1) = Mid(n, 2)
    wY(2) = Mid(n, 2) * -1
  Else
    ReDim wY(1 To 1)
    wY(1) = n
  End If
 
  n = r.Cells(1, 3).Value
  If Left(n, 1) = "±" Then
    ReDim wZ(1 To 2)
    wZ(1) = Mid(n, 2)
    wZ(2) = Mid(n, 2) * -1
  Else
    ReDim wZ(1 To 1)
    wZ(1) = n
  End If
 
  For Each dX In wX
    For Each dY In wY
      For Each dZ In wZ
        x = x + 1
        v(x, 1) = dX
        v(x, 2) = dY
        v(x, 3) = dZ
      Next
    Next
  Next
 
  getDim = v
 
End Function
・ツリー全体表示

【77488】Re:タイで実行するとエラーになります
回答  ウッシ  - 15/10/16(金) 13:56 -

引用なし
パスワード
   こんにちは

英語版なら、コメントやファイル名にも日本語は使わない方がいいですよね。

変数または定数「gFormat」には何がセットされていますか?

エラーになる時の「strFileName_Write」はどのような内容ですか?


・ツリー全体表示

【77487】タイで実行するとエラーになります
質問  とし  - 15/10/16(金) 13:27 -

引用なし
パスワード
   お世話になります。

Windows7pro32bit Excel2010のVBAについて質問させていただきます。

エクセルファイルを読み込んで、得意先コード別に
エクセルファイルを分割して出力する処理を作成しました。

日本(日本語OS)では正常に処理されるのですが
タイ(英語OS)では下記のエラーが表示され正常に処理されません。
(日本・タイ共に同一のインプットファイルを読み込んでおります。)

何か思いつく原因はありますでしょうか?ご教示ください。

====================================================================================================
■エラー情報
Error
Number   :1004
Description:Method 'SaveAs' of object '_Workbook' failed

====================================================================================================
■ソースプログラム(抜粋)

  'Buyer Department Codeを設定する
  strBuyer_Department_Code = ThisWorkbook.Worksheets(1).Range("G" & j).Value

  'ブック名を設定する(元エクセルファイル名_年月日_Buyer Department Code)
  strFileName_Write = strFileName_Left & "_" & Format(Date, "yyyymmdd") & "_" & strBuyer_Department_Code & strFileName_Right
  
  '確認メッセージを非表示にする
  Application.DisplayAlerts = False
  
  'エクセルを出力する
  ActiveWorkbook.SaveAs Filename:=strFileName_Write, FileFormat:=gFormat ← ※おそらくここでエラーになっております※

  'ブックを保存する
  ActiveWorkbook.Close

  '確認メッセージを表示に戻す
  Application.DisplayAlerts = True

====================================================================================================
・ツリー全体表示

【77486】Re:数値がプラスマイナスのとき、データ...
お礼  みか  - 15/10/16(金) 12:40 -

引用なし
パスワード
   βさん回答ありがとうございました。
自分なりにループして作成できました。
本当に助かりました。
今後も日々勉強します。
ありがとうございました。
・ツリー全体表示

【77485】Re:数値がプラスマイナスのとき、データ...
質問  みか  - 15/10/16(金) 8:47 -

引用なし
パスワード
   βさん回答ありがとうございます。
説明不足ですみません。

データが複数ある場合は、更にループをすれば良いのでしょうか?

例えば

  X  Y  Z
   ±50  ±40 ±5
    50  ±40  5
   ±30  20   6

の時、下記データに変換したいのです。

   X   Y  Z
   50   40   5
   50   40  -5
   50  -40   5
   50  -40  -5
  -50   40   5
  -50   40  -5
  -50  -40   5
  -50  -40  -5 
   50   40   5
   50  -40   5
   30   20   6
   -30   20   6

以上のようにしたいのですが、アドバイス頂けるとありがたいです。
よろしくお願いします。
・ツリー全体表示

【77484】Re:参照渡しと値渡し
発言  β  - 15/10/16(金) 8:08 -

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

(アップ後、一部、加筆訂正)

思い出しました。
別の板で、オブジェクトのキーワード や ローカル変数について で
トピを立てられたかたでしたか。

ちなみに、別板で、【私ならこう表現する】と書いて締められた、その【模範説明文】にも
おかしなところはたくさんありましたよ。

様々なことに疑問をもたれるのは結構なことだとは思いますが、
まぁ、法律の文章にも、あやふやな、矛盾のあるところもおおいですし。

>結果を見ればクーロンを渡していることになります。

結果ではなく、これは(ご存じだったかどうかは別にして)そういう仕様です。

むしろ気になるのは(Nob10さんは、そうではないと思いますが)
Call mySub(a) と mySub (a) が 【同じもの】だと思いこんでいる人が多いということです。
いいかえると mySub (a) を Call文でかくと Call mySUb((a)) ということだいうことが
わかっていない人が多いということです。

>つまり、ByRef、ByVarを書くべきところは呼出元であると思います。そうすれば何の問題も起こりません。

特段、異論はありませんが、そうでなくても何の問題もないと思いますが?

>”受け側の規定に基づいて、渡すほうで何かしている?“という記述は渡すほうが受け側に行って、一度お伺いを立ててから戻って、もう一度受け側に行って情報を与えると言うことなのでしょうか?

コンパイラーの機能はご存じですよね。
実行の開始前に呼び出し先があるかどうかを、コンパイラーがチェックしていますよね。
なので、呼び出し先指定がどうなっているかは、実行前にわかっていますね。
ですから、【もしかしたら】と書きました。ただし検証はできません。
少なくとも、【一度お伺いを立ててから戻って、もう一度受け側に行って情報を与える】という
ばかなことは、するはずがないですね。

まぁ、別板でもありましたように、疑問を共有して、ディスカッションするというより
【君たちの理解は間違っている】と主張されるかたのようですから、βは、これで撤収します。

別板でも感じましたが、ご意見は、このような掲示板で声高に唱えられるより、正式にMSに
提言されてはいかがですか?
・ツリー全体表示

【77483】Re:参照渡しと値渡し
発言  ichinose  - 15/10/16(金) 5:33 -

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

>(〜受け)と言ったほうがよいのではないかと思います。
言葉の問題は、歴史を紐解かないと理解できないことがあると思いますよ!!
パラメータ渡し、私が30年前に使っていた低級言語では、値渡しという概念がない言語でした。参照渡しだけです。方式が一つしかないのですから、言葉として参照渡しで
問題がないですね!! こんな時代が長く続いた後に 値渡し方式がでてくると、
言葉使い方で  参照渡しと値渡し というワードが自然に定着しても 違和感がなくなってしまいます。


因みに変数宣言だって

Dim A As Long

このDimって dimensionの略です。私のイメージですとこれは次元という意味なので、
言葉的には、違和感がありますよね!!

私の以前使っていた言語では 

Dcl A As Integer

declare 宣言する  の方がしっくりきます。

歴史的にみると、

昔のBasicには、変数宣言がありませんでした(N88Basicの時代)。

ですから、いきなり a,b,cなどの変数がとびでてくることになります。

配列だけは、

Dim Ary(15)

Dim ary(10,20)

と規定が必要でした(10未満は要らなかった)

Basicで変数宣言が可能になったとき、このなごりで
dim a as integer

になったのでしょう。


パラメータ渡しの話に戻ると、オブジェクトのプロパティをパラメータに使っても
値渡し扱いになりますね!!


Sub test()
  Call test2(Range("a1").Value)
End Sub
Sub test2(ByRef myval As Variant)
  myval = 123
End Sub


test実行でセルA1に変化ないですよね
・ツリー全体表示

【77482】Re:参照渡しと値渡し
発言  Nobu10 E-MAIL  - 15/10/16(金) 5:33 -

引用なし
パスワード
   結果を見ればクーロンを渡していることになります。
呼出元が呼出先の要求を無視するのであれば、呼出先で(〜渡し)を指定する必要が無いと思います(指定しても無視される時があるから)。呼出元に一任すれば何のことはありません。つまり、ByRef、ByVarを書くべきところは呼出元であると思います。そうすれば何の問題も起こりません。回答の中で、”受け側の規定に基づいて、渡すほうで何かしている?“という記述は渡すほうが受け側に行って、一度お伺いを立ててから戻って、もう一度受け側に行って情報を与えると言うことなのでしょうか?もしそうだとしたらこのような事も渡す側でByRef、ByVarを指定すると必要が無くなり全てすっきりすると思います。
・ツリー全体表示

【77481】Re:参照渡しと値渡し
発言  β  - 15/10/16(金) 2:47 -

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

ついでに老婆心ながら。

メソッドあるいは関数 (引数) と記述する人がいます。
↑で申し上げたことを理解して、あえてそうしているならいいのですが
ほとんどは、理解せずに使っている。

たとえば MsgBox ("こんにちは")

たまたまエラーにはなりませんが、これは【間違った】記述です。

MsgBox にはメッセージの他に、ボタンの種類なんかも指定できますよね。

MsgBox ("こんにちは",vbInformation)

このようにコードペインに打ち込んでエンターしてみてください。
コンパイラーに叱られますねぇ。

MsgBox "こんにちは",vbInformation

これが正しい書き方です。

MsgBox ("こんにちは") は、なぜOKなのか?

それは この ( ) が 引数に対してつけられたものではなく、その中の1つの変数に対して
つけられたものだからです。

つまり、

MsgBox ("こんにちは"),vbInformation

といったように、第1引数を ( ) で囲んでいるということなんです。

で、この( ) で囲まれた変数は、前レスで説明したクローンになります。
・ツリー全体表示

【77480】Re:参照渡しと値渡し
発言  β  - 15/10/16(金) 2:22 -

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

まぁ、〜渡し なのか、〜受け なのか これは 言葉のあや と考えればいいとおもいます。
厳密にいうと、指摘の通り、規定しているのは 受け側ですから、〜受け がいいのかもしれません。
おそらくそうだと思いますが、もしかしたら、受け側の規定に基づいて、渡すほうでなにかしている?
そうでないということは、私のレベルでは検証できないので。

mySub(a) と書いておられますが、ほんとは、ちょっと違っていますよね。
mySub (a) 、mySub と ( の間にスペースがありますね。 たとえ、コードペインで mySub( と、くっつけて
タイプしてもエンターをすれば自動的にスペースが挟まれますね。
これをCallステートメントで記述すると Call mySub((a)) と、スペースは挟まれません。

まぁ、それはさておき、Call mySub(a) と Call mySub((a)) 、ないしは mySub a と mySub (a) の違いですけど
変数を ( ) で囲むと、その変数の「クローン」がメモリー領域にテンポラリーに生成され、それを渡すことになります。
つまり、(a) の場合、 a そのものを渡してはいないんです。a の影武者です。
ですから、byRefの受け側のプロシジャで、たとえ焼かれようと煮られようと、殺されようと、
本物の a はぴんぴんしているわけです。

ご理解いただけましたでしょうか?
・ツリー全体表示

【77479】参照渡しと値渡し
質問  Nobu10 E-MAIL  - 15/10/16(金) 2:05 -

引用なし
パスワード
   (〜渡し)と言えば渡すほうに主導権があると思います。他のプロシージャへ変数を受け渡しするとき呼出元でのステートメントの書き方は Call mySub (a)などの様に、どの渡しでも同じです。しかし呼出先プロシージャでは受ける変数の前にByRef又はByValと区別しています。つまり(〜渡し)は呼出元ではなく呼出先プロシージャの主導権によって決定されると言っていいのではないでしょうか。すれば(〜渡し)と言うより(〜受け)と言ったほうがよいのではないかと思います。しかし下記のプロシージャでは呼出先でByRefと参照渡しを指定しているのにかかわらず、値渡しになるようです。ここでは、Callステートメントを使用しないでmySub(a)と変数を()で括ると値渡しになり呼出元が主導権を握っています。言いたいことは、(〜渡し)は呼出元プロシージャによって決まるか呼出先プロシージャなのかと言うことです。
Sub Test()             Sub mySub(ByRef aa As String)
Dim a As String            aa="エクセル"
a="Excel"             End Sub
mySub(a)
MsgBox a
End Sub
どなたか説明できる方はよろしくお願いいたします。
・ツリー全体表示

【77478】Re:数値がプラスマイナスのとき、データ...
発言  β  - 15/10/15(木) 20:13 -

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

もう少しコードを整理して、ループによるコード圧縮もできますがとりあえず。

Sub Test()
  Dim wX As Variant
  Dim wY As Variant
  Dim wZ As Variant
  Dim dX As Variant
  Dim dY As Variant
  Dim dZ As Variant
  Dim v As Variant
  Dim n As Variant
  Dim x As Long
  
  ReDim v(1 To 2 * 2 * 2, 1 To 3)
  
  n = Range("X1").Value
  If Left(n, 1) = "±" Then
    ReDim wX(1 To 2)
    wX(1) = Mid(n, 2)
    wX(2) = Mid(n, 2) * -1
  Else
    ReDim wX(1 To 1)
    wX(1) = n
  End If
  
  n = Range("Y1").Value
  If Left(n, 1) = "±" Then
    ReDim wY(1 To 2)
    wY(1) = Mid(n, 2)
    wY(2) = Mid(n, 2) * -1
  Else
    ReDim wY(1 To 1)
    wY(1) = n
  End If
  
  n = Range("Z1").Value
  If Left(n, 1) = "±" Then
    ReDim wZ(1 To 2)
    wZ(1) = Mid(n, 2)
    wZ(2) = Mid(n, 2) * -1
  Else
    ReDim wZ(1 To 1)
    wZ(1) = n
  End If
  
  For Each dX In wX
    For Each dY In wY
      For Each dZ In wZ
        x = x + 1
        v(x, 1) = dX
        v(x, 2) = dY
        v(x, 3) = dZ
      Next
    Next
  Next
  
  Range("X1").Resize(UBound(v, 1), 3).Value = v
  
End Sub
・ツリー全体表示

【77477】数値がプラスマイナスのとき、データ増や...
質問  みか  - 15/10/15(木) 19:42 -

引用なし
パスワード
   みなさん、こんばんは。
vba初心者のため、上手く伝わるか分かりませんが、よろしくお願いします。

セルのデータが±で始まる時、データをプラスとマイナスに分けたデータに作りかえたいのです。

例1
  X  Y  Z
  ±50  ±40 ±5

の時、下記データに変換したいのです。

   X   Y  Z
   50   40   5
   50   40  -5
   50  -40   5
   50  -40  -5
  -50   40   5
  -50   40  -5
  -50  -40   5
  -50  -40  -5

例2
   X   Y   Z
   50  ±40  5

の時は下記のように、

   X   Y  Z
   50   40   5
   50  -40   5

loopでまわしてみたのですが、上手く行きませんでした。
参考程度でもよいのでヒントを下さい。
よろしくお願いします。
・ツリー全体表示

【77476】Re:セル内への文字入力
お礼  桃太郎  - 15/10/15(木) 18:25 -

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

>左辺のSelection は上記で説明した通りですが問題は【右辺】のSelection.
>ここが複合せルですね。複合セルということは複数セル領域です。

>左辺も右辺も配列であれば、転記はできますが、右辺が 配列に単一の値を付加したもの。
>こういった値は生成できません。
>このあたり、ややこしいかもしれませんが、右辺を【単一の値】にする必要があります。


大変わかりやすい説明ありがとうございます。
何が問題なのか、非常によくわかりました。


>Selection.Value = Selection(1).Value & Cells(21, 17).Value
>にしてください。

これで解決できました。ありがとうございます。
Selection(1).Valueで結合セルの最初のセルの値だけ取り出せるわけですね。
こういうのはスキルが低いのかググってもたどりつけないので非常に助かります。


>ところで、Cells(21, 17).Value これって、わかりにくくないですか?
>Range("Q21").Value のほうがわかりやすくないですか?

以前はRangeで書いてましたが、変数を使いたい場合、
Range表現だと非常にややこしい形でないと変数が使えなかったので
以降Cellsで書いています。

前回に続き今回もわかりやすい解説とコード、感謝させていただきます。
ありがとうございました。
・ツリー全体表示

【77475】Re:セル内への文字入力
発言  β  - 15/10/15(木) 17:49 -

引用なし
パスワード
   ▼桃太郎 さん:

Selection.Value = "hoge"

Slectionが結合セルであろうとなかろうと、このコードは 左辺のSelection のすべてのセルに右辺の値が代入されます。
で、Selectionが結合セルの場合は、結果的に、Selectionの先頭セル(結合セルの代表セル)以外の値は空白にされるということです。
結合セルではない、通常の複数セル領域を選択して試してみてください。

それは、さておき、今回の質問ですが、

Selection.Value = Selection.Value & Cells(21, 17).Value

左辺のSelection は上記で説明した通りですが問題は【右辺】のSelection.
ここが複合せルですね。複合セルということは複数セル領域です。

たとえば、 MsgBox Range("A1:A2").Value & "hoge"

こんなコードを実行するとエラーになります。
複数セル領域のValue は 1つの値ではなく【配列】になった値です。
左辺も右辺も配列であれば、転記はできますが、右辺が 配列に単一の値を付加したもの。
こういった値は生成できません。

このあたり、ややこしいかもしれませんが、右辺を【単一の値】にする必要があります。

Selection.Value = Selection(1).Value & Cells(21, 17).Value

にしてください。

ところで、Cells(21, 17).Value これって、わかりにくくないですか?
Range("Q21").Value のほうがわかりやすくないですか?
・ツリー全体表示

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