アプリ版:「スタンプのみでお礼する」機能のリリースについて

セル範囲内に*60したいと思い、以下のようにしましたが、実行後のセル範囲内の値が全て#VALUE!になってしまいました。書き方をどのように修正すればできるでしょうか?
式の中にあるOffsetは、最初は、Offset(0, 0)から始まり、,繰り返しの中で、lastcol分だけ列を移動しながら、60倍していきたいと思っています。シート名は、Withで指定していますが、Evaluate内で、使えないなら、直接シート名を記載しても問題ありません。行範囲も、列の移動に合わせて変動します。(lastrowで決定)

.Range(.Cells(12, 31).Offset(0, lastcol), .Cells(11 + lastrow, 33).Offset(0, lastcol)).Value = Evaluate(" & .Range(.Cells(12, 31).Offset(0, lastcol), .Cells(11 + lastrow, 33).Offset(0, lastcol))).Address(False, False) & * 60")


また、範囲内には空白セルも含まれており、60倍すると、空白セルに0が入力されてしまうのではないか、と思いますが、できれば空白セルは除外して処理できるとよいのですが、その判定をここに入れ込むと式が複雑で分かりにくくなるのではないかと思うので、空白セルもそのまま処理し、その後0を削除する処理も同じようにEvaluateで引き続き処理できれば良いと思っていますので、大変申し訳ないのですが、60倍する式の修正式と、同じ範囲の0を削除する式を教えていただきたいです。
もし、0を削除する式は、Evaluateを使わず、もっとよい方法があればそれでも良いです。Excelの設定で0を表示しない、はNGです。

質問者からの補足コメント

  • 一応、*60の前にAddressをつけているのですが、場所が違いますか?
    ただ、最初の質問の式は、.Addressの前の括弧が3個あるので、1個多いような。2個が正解ですかね。
    Evaluate(" & .Range(.Cells(12, 31).Offset(0, lastcol), .Cells(11 + lastrow, 33).Offset(0, lastcol)).Address(False, False) & * 60")
    と修正しましたが、やはり結果は、#VALUE!ですね。どこかが違うのでしょう。
    あきらめて、For Eachでループさせて計算させた方がよいかもしれません。

    No.2の回答に寄せられた補足コメントです。 補足日時:2019/04/09 23:49

A 回答 (4件)

こんにちは。



いずれにしても、One Line で書くというのは、VBAの場合、どこでミスしたか分かりなくなりますから、分かち書きのほうがよいでしょう。
Test1 は、Evaluete式は、配列計算です。結果的には、空白を抜くという作業が、ややこしくなっています。
Test2 は、VBAの通常の構文を使ったもので、標準的です。

'//標準モジュール
Sub Test1()
 Dim Rng1 As Range
 Dim adr1 As String
 Dim Rng2 As Range
 Dim adr2 As String
 Dim LastCol As Long
 Dim LastRow As Long
 With ActiveSheet
  LastCol = .Cells(1, Columns.Count).End(xlToLeft).Column
  LastRow = .Cells(Rows.Count, 1).End(xlUp).Row
  Set Rng1 = .Range(.Cells(12, 31).Offset(0, LastCol), .Cells(11 + LastRow, 33).Offset(0, LastCol))
  adr1 = Rng1.Address(0, 0)
  On Error Resume Next '空白がない場合
  Set Rng2 = Rng1.SpecialCells(xlCellTypeBlanks)
  adr2 = Rng2.Address
  On Error GoTo 0
  Rng1.Value = Evaluate(adr1 & " * 60")
  If Not Rng2 Is Nothing Then
   .Range(adr2).Value = ""  '0を抜く。"" は残りません。
  End If
 End With
End Sub

'//標準モジュール
Sub Test2()
 Dim LastCol As Long
 Dim LastRow As Long
 Dim c, Rng As Range
 With ActiveSheet
  LastCol = .Cells(1, Columns.Count).End(xlToLeft).Column
  LastRow = .Cells(Rows.Count, 1).End(xlUp).Row
  Set Rng = .Range(.Cells(12, 31).Offset(0, LastCol), .Cells(11 + LastRow, 33).Offset(0, LastCol))
  For Each c In Rng
   If c.Value <> "" Then
    c.Value = c.Value * 60
   End If
  Next
 End With
End Sub
    • good
    • 0
この回答へのお礼

どうもありがとうございました。
思った通りに、うまく動作しました。
そのまま、入れ込むと、
Evaluate(.Range(.Cells(12, 31).Offset(0, paste_col), .Cells(11 + plan_row, 33).Offset(0, paste_col)).Address(0, 0) & " * 60")
ということだったのですね。
文字列の所は、""から出して、&で繋げるということですね。
空白を抜く操作がなければ、シンプルになりそうですね。
分かりやすさでは、普通のループの方がいいですね。

お礼日時:2019/04/10 12:43

抑も、


此のEvaluate文の 内側は、
貴方の 意図では、
どの様な 文字列に、
なっていて 欲しいのですか?

先ずは 其れから
お伺いしますよ?


だって、
文字列としての 繋ぎ具合を、
ミスってませんか?

先ずは、
どんな文字列を 生成したいかを、
教えてくださいね。

所で、
Evaluate構文は、

確かに Evaluate("…")と
多く 紹介されてますが、

例えば、
文字列定数の 値を、
渡す時や、
其の他に おいて、

必ずしも 「"」が、
必要な訳では ありません。


一般的には、
文字列だから、
「"」で 始まり、
「"」で 終わる、

ただ 其れだけで、
意味合いを 示しただけであって、

要は
文字列を 与えれてれば、

Constした 名前でも、
type宣言変数中に ある、
文字変数でも、
勿論 文字列配列でも、
勿論 「"」無しでも、

何でも 良いのです。


ので、
Evaluate(" & . Range…
& * 60")
は 変な事に、
なってますよね?


抑もから 文字列状態の物に、
「"」と 付ける、
必要ありますか?

) & * 60")
て 変じゃないですか?

そう考えると 変だと、
解りますよね?


後、
次元が 一致していないかもです、

Evaluate構文は Variant型で、
受け取るのが 普通ですよ〜、

其れとも 此は、
対策済みですか?


では、
こんな お困り事の、
時は 如何するか、
ですね、

こんな時は、
ウオッチウインドウを 持ち出すと、
謎が 解け易いですよ。


今回も、
Evaluateの 内側、
一部、
又は 全部を、
ウオッチウインドウに 登録して、

ステップインから 一行実行の末、
此の Evaluate文に、
キャプションを 移した時、

意図した 文字列に、
ちゃんと 変換されているかを、
確認くださいね、

すると よく解りますよ、


ので、
今回は 私にも、
ウオッチウインドウに、
どう 表示されたかを、

補足等で 構いませんので、
教えて 頂けますか?


更に、
もし 意図した通りに、
ウオッチウインドウに 文字列として、
変換されたなら、

Evaluate構文全体を 登録して、
結果、
どの様な物に なったかを、

此も
捕捉にでも 報告を、
頂けますか?


Evaluate構文は 楽しいですよね、
但、
扱いが 複雑で、
困惑しますよね、


特に、
結果を Sheetに、
還元するのが 難しくて、
困ります。


使える方が とても少ない、
希少技術で、

問うても なかなか、
答えが 得れないかも、
知れません、

其の意味では、
今回は、
私か 目にしたので、
ラッキーでしたね。


まぁ、そんなこんな故に

厳選された 一人に、
なれる 技術ですので、

苦悩も 多いでしょうが、
頑張って くださいね。


OKWEBや、教えてconecoや、Yahoo!知恵袋で、
推進してた 一人として、

チャレンジ 頂いているのは、
嬉しいですね。
    • good
    • 0

内容は 精査してませんが、


少なくとも 言える事、
不備は あります。


Evaluateは 文字渡しが、
基本な事は ご存じですよね?

しかし、
拝見すると 左にあらず、
配列渡しに なってます、

此は 頂けませんね。


試しに、
レンジ指定部 後方に、
.ADRESS
と 付けてみては、
如何ですか?

位置を 文字列で、
渡せますよ?


Evaluateを 諦め、
ループを 回す等、

objectタッチ数が、
飛躍的に 増えますから、

VBでは いざ知らず、
VBAでは 愚の骨頂です。


受け入れず、
最低限に 留め、
お留まり下さいね。
この回答への補足あり
    • good
    • 0

イメージを間違えているのかもしれませんが、どこからどこの範囲のセルを対象にされているのでしょうか。

 下の場合、LRowは、自分で数値を決めるlastrow、LColは、自分で数値を決めるlastcolのつもりです。
対象範囲がはっきりしていれば、空白でなく、数値のセルだけを書き換えるという方法で済ませてしまってはマズイのでしょうか。

Sub kari()
S1Row = 12: S1Col = 31
S2Row = 11: S2Col = 33
LCol = 15: LRow = 15
With ActiveSheet
Set ULc = .Cells(S1Row, S1Col + LCol)
Set DRc = .Cells(S2Row + LRow, S2Col + LCol)
Set target = .Range(ULc, DRc)
target.Select
For Each r In target
If r <> "" Then
If IsNumeric(r.Value) Then r.Value = r.Value * 60
End If
Next
End With
End Sub
    • good
    • 0
この回答へのお礼

For Eachでループさせるやり方は分かるのですが、たまたまEvaluateというのがあると知り、これで処理できれば高速に処理できそうで便利そうだったので使えればよいな、ということで質問させていたできました。
無理なら、For Eachで済ませます。

LColは、For~Nextのループ内で次々に値が変動するので固定できません。そのまま左辺をSet targetに放り込めば、以下は提示していただいたコードで動作としては実現できます。
Set target =.Range(.Cells(12, 31).Offset(0, lastcol), .Cells(11 + lastrow, 33).Offset(0, lastcol))


どうも、ありがとうございました。

お礼日時:2019/04/09 23:39

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!