Excel VBA 質問スレ Part17

このエントリーをはてなブックマークに追加
802デフォルトの名無しさん:2011/02/03(木) 01:33:08
Variantの話じゃなくてすまん、ユーザー定義型だったら方法ないよね?
配列になってたらEraseでいけたと思うけど。
803デフォルトの名無しさん:2011/02/03(木) 03:03:54
ない
804777:2011/02/03(木) 04:58:48
>>780

分かりやすいサイトを紹介していただき、ありがとうございます。
シンプルなものですが、クラスモジュールを使ってカラーパレットを作ることができました。

ラベルを配列にしたからか、イベント処理をフォーム側には書けませんでした。クラスモジュール側に書いたらできました。
正直あまり理解できていませんが。
805デフォルトの名無しさん:2011/02/03(木) 13:44:07
>>802
同じユーザー定義型を作って代入する
806デフォルトの名無しさん:2011/02/03(木) 16:21:37
>>798,>>800
おぉーEmpty値を代入すればよかったんですね!
おかげ様でこれからはスマートに書けますよ、ありがとうございましたー
807デフォルトの名無しさん:2011/02/03(木) 18:42:16
全シートの全セルをコピーして一つのシートに移動させたいんですけど、

Worksheets.Select

Cells.Copy
Sheets("Sheet1").Select
Range("A1").PasteSpecial Paste:=xlAll


なぜこれでできないんですか?お願いします
808デフォルトの名無しさん:2011/02/03(木) 19:08:53
何がやりたいのか判らんが

Cells.Copy

と(シートを指定せずに)書いた場合、アクティブシートのすべてのセルを表す
Range オブジェクトが返される

従って、シート1がアクティブシートならば、シート1からシート1がコピーされる

そもそも、各シートの全セルの個数は同じなのだから、それをひとつのシートに
移動は無茶だと思う
809807:2011/02/03(木) 19:23:14
>>808
なるほどなぜできないかよくわかりました。

既に50個あるシートの中身を新規シートを作成し、その中に全て移すというVBAが作りたいのです
810デフォルトの名無しさん:2011/02/03(木) 19:50:23
データの中身が判らないと何とも言えない

まず、幾つかのシートのコピーを手作業で試してみたら?

どういう風にやったらいいか見えてくるかもね

通常は、使ってる範囲だけを位置をずらしながら、
コピーすればよいという事になるとは思うけど

シート1の情報

シート2の情報

シート3の情報

などなど
811デフォルトの名無しさん:2011/02/03(木) 22:26:51
UsedRangeでいいんじゃないの?
812デフォルトの名無しさん:2011/02/04(金) 02:08:09
A B     
1 北海道
2 北海道
3 北海道
4 北海道
1 青森県
2 青森県
3 青森県
1 岩手県
2 岩手県


今こうなってるのを、
北海道のナンバーを全て1に。青森県は2に。岩手県は3に
と、いった具合にVBAで組みたいのですが、どのようにすればいいでしょうか?
もしくはなんとぐぐればよいでしょうか?
813デフォルトの名無しさん:2011/02/04(金) 03:23:43
新しいナンバリングは何を元に決めるの?
出現順の連番でいいなら、出現リストを生成・保持しながらループする感じで

上から順にループ処理、値を順次取り出して出現リスト内にあるか検査 (1週目、北海道を照合)
 (結果A)リストにない→ 出現リストに新規追加し新しいナンバーを割り当て (1週目、北海道が1と決定)
 (結果B)リストにある→ 何もしない (2〜4週目の北海道など)
この時点で新ナンバーは確定しているので、新ナンバーを該当セルの横に設定
これを最後のセルまで繰り返す 以上

出現リストはDictionaryオブジェクトを使うといいかな。
同時に新ナンバーのリストとしても使えるから。
Existsメソッドを重複検査に使用。FalseならAdd、値として新ナンバー入れとく。
あぁ、そういや存在しないキーでいきなり参照すると自動的にAddされる特性があるから、
NewNum=Dic.Item(県名)で、NewNum=0なら新ナンバー生成でもいいね(その場合0は新ナンバーに使用不可)

つーかこれVBAでやるより作業用セルに数式書いてフィルしたほうが作業的には早いよ
VBAでやりたくてしょうがないなら何も問題ないけど
814デフォルトの名無しさん:2011/02/04(金) 03:54:00
>>812
A1=1
A2=A1+(B1<>B2) 以下オートフィル
815デフォルトの名無しさん:2011/02/04(金) 04:11:46
>>814
それは同じ県はかならず一つにまとまってるって前提が必要だと書いといてやれよ
俺的にはどっかに県のコード一覧表つくっといてlookupが良いと思うぞ

VBAスレなのにVBAいらないけどな
816デフォルトの名無しさん:2011/02/04(金) 12:43:19
>>812のナンバリングってCOUNTIF使ってたりしてな。
817デフォルトの名無しさん:2011/02/04(金) 13:41:49
>>815
LOOKUPじゃなくてVLOOKUPだろ?
818デフォルトの名無しさん:2011/02/04(金) 22:13:22
はじめまして
マクロでブック名を一括で変更したいのですが、
ブック名に文字化けを含む場合、エラーになります。

変更はNameを使用していますが、文字化けしたブック名を
変数に代入すると文字列が変わってしまう(â→a等)ようで、
変更前のブックのアドレスをうまく指定できません。

ブックを開かずに文字化けしているブック名を変更する方法はあるでしょうか?
819デフォルトの名無しさん:2011/02/04(金) 23:07:35
>>818 ブック名でアクセスしなきゃいいんじゃね?
Workbooks(1).Name= "新しいシート名"

文字化けした名前を取り出したいってのは無謀だと思うぞ
つかなんで化けたのか
820デフォルトの名無しさん:2011/02/05(土) 00:00:13
はじめまして質問させてください。
Excel 2007でInputboxから日付を入力してAutofilterしたいのですが
うまく検索してくれませんコードは

Private Sub

Dim TMP As String
TMP = InputBox("分析日を入力してください", "分析日入力", Format(Date, "yyyy/m/d"))
If TMP = " " Then Exit Sub

ActiveSheet.Columns("A:A").EntireColumn.AutoFit
ActiveSheet.Columns("A:A").Select
Selection.NumberFormatLocal = "yyyy/m/d"
Selection.AutoFilter
'ActiveSheet.Range("$A$1:$P$255").AutoFilter Field:=1, Criteria1:=DateValue(TMP)

End Sub
です。

Criteria1:= 以降を "<>"&TMP  や  "="&TMP  に変更しても
検索できませんでした。どうしたら検索できるのでしょうか?
821デフォルトの名無しさん:2011/02/05(土) 02:50:50
>>819
横レスだけど、ブック名はユニコード、VBAの文字列はShift-JISベースで、一部の文字は
文字列変数に代入する時によく似た文字に勝手に変換される場合があるんだよ

海外から送られてきたブックなんかだとご当地の言語でブック名が付けられていたりして
VBAでまともに扱えなくて困る場合がある
822デフォルトの名無しさん:2011/02/05(土) 04:07:21
>>820

私の環境では、試してみたらできたけど。
もちろん、プロシージャに名前付けてますよね?
>Private Sub

823デフォルトの名無しさん:2011/02/05(土) 04:36:08
>>821
あぁそうか、Excelはオブジェクトなんだった
なるほど、Excel側のシート名はExcel管轄なのね…
ちなみにVBAはS-JISではなくUnicodeなんだが、まぁそれはともかくなるほど…
(VBは自分以外はShiftJISが基本だと思い込んでるので勝手にUni→S-JIS変換をかましてしまうのよ)

じゃ化けた文字列を再びシート名にする事は不可能か
ワークシートやVBAから名前で呼び出してたらアウトー、だな
824デフォルトの名無しさん:2011/02/05(土) 06:43:45
>>820
貼り忘れでした。
Private Sub 分析結果の読み込み_Click()

このようにコマンドボタンに登録しています。
ちなみにどのやり方でできましたか??
825デフォルトの名無しさん:2011/02/05(土) 07:51:19
>>824

A列しか入力してないけど、適当に日付を入れて、
>>820 のコードほとんどそのまま入力してできました。
$P$255を$A$255にしただけ。

>'ActiveSheet.Range...
のシングルクォーテーションは、実際は外しているんですよね?

簡単にデバッグできそうだから、どこかにシートをUpできるようなら見ますよ。
826デフォルトの名無しさん:2011/02/05(土) 09:22:17
>>825
今試してみたけどやはり

254レコード中0件がヒットしました

となり検索できませんでした。

一度見てもらいたのですがUpする場所はどこがよろしいでしょうか?
827デフォルトの名無しさん:2011/02/05(土) 09:55:59
>>825
斧にZIPでUpしました。添削のほうよろしくお願いいたします。

Sc_201766.zip

828デフォルトの名無しさん:2011/02/05(土) 11:44:28
>>827
すみませんが、ダウンロードのキーワードを教えてください。
829デフォルトの名無しさん:2011/02/05(土) 11:51:10
>>828
うっかりしてました。
2323です。
よろしくお願いします。
830デフォルトの名無しさん:2011/02/05(土) 12:45:37
>>829
「参考.xls」のA列が日付じゃなくて文字列になっているのが原因。
はじめから日付にしておくほうがいいと思いますが、
どうしても日付にできないようなら、例えば、

ActiveSheet.Range("A1").Activate
Do While ActiveCell.Value <> ""
ActiveCell.Value=DateValue(ActiveCell.Value)
ActiveCell.Offset(1).Activate
Loop

のようなコードを分析日入力の後くらいに入力すればうまく働きます。
831デフォルトの名無しさん:2011/02/05(土) 12:59:29
>>819
あと、文字列で検索するって割りきるのなら、最後の行のCriteria1を、
Criteria1:=Format(DateValue(TMP),"yyyy/mm/dd")
と変更してもうまく働きます。
832831:2011/02/05(土) 13:00:52
上、間違えました。
>>819 じゃなくて >>829 です。
833829:2011/02/05(土) 14:19:19
>>832
無事できました!
マクロの記録で
ActiveSheet.Columns("A:A").Select
Selection.NumberFormatLocal = "yyyy/m/d"
としてA列を日付にしていたつもりなのですが
できていなかったのですね。

とても助かりました。ありがとうございました。
834デフォルトの名無しさん:2011/02/05(土) 15:02:41
>>833
それは、良かったです。

あと、気になるところもいくつかあります。

If TMP = " " Then ... は、
If Not IsDate(TMP) Then
のような感じにしたほうが、いいと思います。

AutoFilterメソッドは、範囲を自動選択に任せて、
ActiveSheet.RAnge("$A$1:$P$255).AutoFilter ... を、
ActiveSheet.Range("A1").AutoFilter ...
にして、上の行のSelection.AutoFilterもいらないです。

A列が選択されたままになっているので、例えば、
ActiveSheet.Range("A1").Select
のような文をどこかに入れるなどしたいです。
(1行目には項目名が入っていると思います)

「$」記号は、セルの式のコピー、ペースト時の相対参照、絶対参照の区別のためにあるので、
VBAのコード内では、セルに式を入力するという用途以外では、無意味だと思います。
835デフォルトの名無しさん:2011/02/05(土) 15:31:47
>>834
ご指摘のように修正させていただきました。
とても勉強になります。

また試行錯誤して分からないところがありましたら
よろしくお願いいたします。
836デフォルトの名無しさん:2011/02/05(土) 19:41:37
>>819>>821
返答ありがとうございます。

文字化けしてるのは海外のご当地言語が使われることもあるためです。
出来ればVBA上で一括管理したかったのですが、
Excelで文字化けしたファイルを扱うのは難しそうですね。
Excel以外のソフト等も使ってやってみます。
837デフォルトの名無しさん:2011/02/05(土) 20:05:08
>>836
手元に2007しかありませんが、Excelのオプションで
言語設定があるようですが、これは役に立つかも?

使えなかったら、ごめんなさい
838デフォルトの名無しさん:2011/02/05(土) 20:18:21
質問なんですけど
今インベーダー風のゲームを作っていてy座標の小さい方から大き方へ弾を撃ち出して
的に当て用途しているところなんですが

'ビーム砲が画面最上に達しているとき
If lngBeamY = 144 Then
'ビーム砲発射フラグをOFF
blnBeamF = False
'ビーム砲を消去
rngClear8.Copy _
Destination:=Range(Cells(lngBeamY, lngBeamX) _
, Cells(lngBeamY + 7, lngBeamX + 7))

'ビーム砲が画面最上に達していないとき
Else
'縦位置の計算(縦移動)
lngBeamY = lngBeamY + 4
'ビーム砲を描画
rngBeam.Copy _
Destination:=Range(Cells(lngBeamY, lngBeamX) _
, Cells(lngBeamY + 7, lngBeamX + 7))
End If

というコードで的を外れて通り越して行ったとき弾を消し、次の球を撃てるようにしたいんですが
指定した座標を通り越しても移動を続け次の球が撃てません
だれかアドバイスをください

839デフォルトの名無しさん:2011/02/05(土) 20:27:25
>>838
'ビーム砲が画面最上に達しているとき
If lngBeamY = 144 Then

↓ ここを修正

If lngBeamY >= 144 Then

あと、上下が逆じゃない?
パソコンの画面のY座標は数学で習う座標と上下逆にするのが普通だよ
840デフォルトの名無しさん:2011/02/05(土) 20:37:52
>>839
丁寧な説明ありがとうございます

上下逆にする覚えときます。
841デフォルトの名無しさん:2011/02/05(土) 21:40:23
質問です。

VBAで、エクセル以外の画面をアクティブにできないようにする
方法はあるんでしょうか。
842デフォルトの名無しさん:2011/02/05(土) 22:05:33
2003ではじめたばかりの初心者です。

写真をセル幅にぴたりとはめたいのですが、横幅がうまくいきません
写真の縦の縮小サイズから、横の縮小サイズを計算してセル幅に指定しようとしています。
Columns(buf).Width = Int(myHeight * ratio)
アドバイスお願いします。
843デフォルトの名無しさん:2011/02/05(土) 22:15:50
>>842

パッと見た感じだと、
myHeightじゃなくて、myWidthじゃないかと思いますが、
もう少し詳細を教えてもらったほうが答えやすいと思います。
844デフォルトの名無しさん:2011/02/05(土) 22:33:49
>>843

すみません。
myHeightは、写真挿入前にポイントでセルの高さを指定しています。
写真は、縦のセルサイズに合わせて比率固定で縮小してます。

たとえば、セル縦300ポイント、写真縦横比が4/3だったら、
セルの横幅を400ポイントにしていすれば、写真とセルのサイズが合うかな・・・と。
この横幅のポイント指定が、1004エラーで上手くいきません。

845デフォルトの名無しさん:2011/02/05(土) 22:52:48
>>844
Width を
ColumnWidth
にすれば、どうですか?
846845:2011/02/05(土) 22:57:03
ポイント単位だからColumnWidthは的外れでした。
もう少し考えます。
847デフォルトの名無しさん:2011/02/05(土) 23:24:50
>>844

Width プロパティはポイント単位で取得のみ、
ColumnWidth プロパティは数字の「0」の幅の単位で、取得/設定可能。

なので、ピッタリした値にはなりませんが、
Dim xx as Double
...
With Columns(buf)
 xx = .ColumnWidth / .Width
 .ColumnWidth = Int(myHeight * ratio) * xx
End with

どうでしょうか...?
848デフォルトの名無しさん:2011/02/05(土) 23:33:15
>>847
エラーの理由は理解できました。
ありがとうございます。

やはりぴったりにこだわりたいので、違う方法でもう少し考えて見ます。
849デフォルトの名無しさん:2011/02/05(土) 23:52:45
>>848

そうですか。分かったらぜひ教えてください。
一応、>>847 の誤差を小さくした改良版(?)も載せておきます。

Dim xx As Double
Dim preXx As Double
Dim num As Integer
...
num = Int(myHeight * ratio)
With Columns(buf)
 xx = .ColumnWidth / .Width
 Do
  .ColumnWidth = num * xx
  preXx = xx
  xx = .ColumnWidth / .Width
 Loop While preXx <> xx
End With


850デフォルトの名無しさん:2011/02/06(日) 02:38:22
XPのExcel2007です。皆さんは時間計測を何でやってますか?
一定間隔で計測をやりたくなって、以下のようなサンプルを
作ってみました。今のところ、timeGetTime() でそれなりに
動いていますが、定石があれば教えて頂けないでしょうか?

On Error Resume Next
Cntr = 0
Tnxt = 0
Tsta = timeGetTime()
While (Cntr < 100)
 Tnow = timeGetTime() - Tsta
 If (Tnow >= Tnxt) Then
  Worksheets("Sheet1").Cells(1, 1).Value = Tnow
  Cntr = Cntr + 1
  Tnxt = Tnxt + 200
 End If
 If ((Tnow Mod 1000) = 0) Then DoEvents
Wend
851デフォルトの名無しさん:2011/02/06(日) 03:29:42
>>850
一定の周期で処理を繰り返す場合の定石はSetTimer/KillTimer
852850:2011/02/06(日) 09:27:23
>>851
レスどうもです。
ループで待つのに抵抗があったところでした。
割り込みも試してみたいと思います。
853デフォルトの名無しさん:2011/02/06(日) 09:59:58
多重ForEach文の中から1つだけ上に抜けたいんですが
Exit Forすると全部抜けちゃいます
1つだけ抜ける良い手はないでしょうか?

ForEachをやめてForとDoの入れ子にするってのもありますが、
3重4重のでもどうにかなる方法ないかなぁと・・・

>>851
一時停止時にコールバック受けたらExcelごとクラッシュするんでわ?
854デフォルトの名無しさん:2011/02/06(日) 10:26:48
>>853
むーん。以下、Excel2007のヘルプのコピペ。

>Exit For
> For Each...Next ループまたは For...Next ループを抜け、Next ステートメントの次のステートメントに
> 制御を移します。For Each...Next ループまたは For...Next ループの中でだけ使用できます。
> For Each...Next ループまたは For...Next ループがネスト (入れ子) 構造になっているときは、Exit For
> のあるループの 1 つ外側のループに制御を移します。

とあるので、他に原因があるんじゃないかな〜
オレのところでも再現しなかった。
855デフォルトの名無しさん:2011/02/06(日) 11:36:47
>>853
ソースを見せてください。

言語に限らず、基本的には1段階ずつしかループは抜けないはずですよ。
856デフォルトの名無しさん:2011/02/06(日) 11:46:00
質問させてください。

Excel 2007でセルの計算式の結果を受けてIFで処理を分けたいのですが
上手くいきません。

具体的にはB1には=(480+(A1)*10)/480*F1)
という式を入れており、その結果次第で
70以下ならC1に=(75-B1)*.48の計算結果をいれ、
70よりおおきければ − を表示させたいのです。

セルに直接IF文を入れることも考えたのですが、C1セルに
直接数値を入力することがあり(計算結果の微調整のため)
マクロで計算させたいのです。

現在記述しているコードは

Private Sub 計算_Click()

Worksheets("sheet2").Select

If Range("B1").Value <= 70 Then
Range("C1").Formula = "=(75 - (B1)) * 0.48"
Else: Range("C1").Value = "-"

End If

End Sub

です。
これを動かしても何も表示されません。
どうすればよいでしょうか?
857デフォルトの名無しさん:2011/02/06(日) 12:09:57
>>856
私の環境ではできました。
どこかにブックごとUpしてもらえれば見ます。
858デフォルトの名無しさん:2011/02/06(日) 12:13:18
>>855
ネストしたループから一気に抜けれる言語はいくらでもあるよ。
例えば php とか java とか。

>>856
うちでも再現しない

> Worksheets("sheet2").Select

sheet1 見てるとかと言うオチじゃないよね?

まずは、ブレークかけてみて本当にそのルーチンが起動されてるか確認してはどうか。
859デフォルトの名無しさん:2011/02/06(日) 12:41:01
>>856

斧でUpしました。
Sc_202214.zip
パスは9898です。

添削よろしくお願いいたします。
860デフォルトの名無しさん:2011/02/06(日) 12:45:39
>>858
それは確認しています。
F8で確認しているのですが
If Range("B1").Value <= 70 Then
のところで実行時エラーがでます。

セルの結合が悪さをしているのでしょうか?
861デフォルトの名無しさん:2011/02/06(日) 12:49:33
> 実行時エラーがでます。

おいおい、「動かしても何も表示されません。」じゃないのかよ。

エラーが出るなら、エラーメッセージ書くとか、エラーコード調べるとかしなよ。
862デフォルトの名無しさん:2011/02/06(日) 12:54:58
>>861
たしかに・・・
自分で書き込んだ後に気付きました。
先ほど動かしてみたら以前はでなかったエラーが
でてきたのでテンパってました。
申し訳ありません。
863デフォルトの名無しさん:2011/02/06(日) 13:03:01
>>860
B1がエラー値なんじゃないですかね?
たしかエラー値を含んでいると数値演算や比較式がエラーになったと思うんですが。

式に現れるA1とF1の中身は数式ですか?
その数式内でほかのセルを参照してませんか?
めぐりめぐってそのB1のValueを決定するために
今実行中、あるいはこの先埋めるはずのセルを参照してませんか?

あるいはほかのVBAが動作しようとしてるのかもしれず、
で、そっちでコケてるのかもしれません。

Excel自身にVBA関数を呼び出させた場合(数式からVBA関数を呼び出すとか)は、
VBAが中断モードになっていてもそれを無視して動作しようとします。
さらにその中で何らかのエラーが起きると何の表示も出さずに強制中断し、
このときValueの値はエラー値になります。

こうなると通常なら絶対にエラーにならないはずのセルがエラーを返したりと
イベント連鎖が読みにくくなりますので、その関係かもしれません。
864デフォルトの名無しさん:2011/02/06(日) 13:07:10
>>859
拝見させていただきました。

結合したセルの値を参照/設定する場合は、
先頭セル(一番左上のセル)に対して行うと良いです。

If Range("L6:N6").Value ... ではなく、
If Range("L6").Value にする。

細かくExcelのVBAの仕様を調べてないので、
そのままでもいいところもあるかも知れませんが、変更してみてください。
865デフォルトの名無しさん:2011/02/06(日) 13:08:32
シート1の最後のセル番地を変数に代入して、
シート2のオートフィルの範囲に適用したいのですが

endcell = Selection.SpecialCells(xlCellTypeLastCell).Count



Range("a1").Value = "=trim(シート1!a1)"

Selection.AutoFill Destination:=Range("A1:endcell"), Type:=xlFillDefault


これではエラーがでます。セル番地を取得する関数はCountではないのでしょうか?
そもそも変数の使い方が間違ってるのでしょうか?どなたかお願いします
866デフォルトの名無しさん:2011/02/06(日) 13:18:10
>>864
上手くいきました!!
("L6")にしたり("L6:N6”)にしたりいろいろ
試していたのですがなかなか思うようになりませんでした。
この2週間ぐらいずっと悩んでいたのが解決しました。
Sub 計算()

Worksheets("Sheet1").Select

  ActiveSheet.Range("L6:N6").Select

  If Range("L6").Value <= 70 Then
  Range("O6:P6").Formula = "=((75 - (L6)) * 0.48)"
  Else: Range("O6:P6").Value = "-"

 End If
End Sub
このように変更しました。ありがとうございました。
>>863
A1・F1はそれぞれ数値を入れています。
VBAは奥が深くまだまだ勉強することが多いです。

レスを下さった皆さんありがとうございました。
また分からないことがあればよろしくお願いいたします。
867デフォルトの名無しさん:2011/02/06(日) 13:25:17
>>865
"A1:endcell"というのは、単なる文字列扱いされています
endcellという変数を与えたいなら、

Range("A1:"&endcell)

という形で書いてくださいな
他にもいろいろ間違えてそうですね

RangeオブジェクトのCountプロパティは単にセルの個数を返します。
でその書き方だと常に1を返します。(LastCellを指定すると単一のセルを返すため)
最終的に"A1:1"という文字列が出来上がってやっぱりエラーでしょうね

セル番地が欲しいなら、.Addressプロパティです。

ちなみに、LastCell指定をしたSpecialCellsは、
その元となる範囲を無視して、該当シート全域から最終セルを探してきます。
たぶん、望んでいるのとは違う答えなんじゃないですかね
868デフォルトの名無しさん:2011/02/06(日) 13:30:27
・・・Excelのシートやブックって、なんであんなに壊れるのん?

急に動かなくなって、数日デバッグしてもどうしても原因わからなくて、
散々悩んだあげくシートを丸コピーして削除したらすっかり直ったり
この怒りをいったいどこにぶつければ・・・
869865:2011/02/06(日) 13:48:45
>>867
ありがとうございます。お察しのとおりダメでした。

Dim endcell As Integer
endcell = Selection.SpecialCells(xlCellTypeLastCell).Address

Worksheets.Add Before:=Worksheets(1)
ActiveSheet.Name = "シート2"

Range("a1").Value = "=trim(シート1!a1)"
Selection.AutoFill Destination:=Range("A1:" & endcell), Type:=xlFillDefault

と、記述しています。

シート1の内容全てにtrim関数で空白を取り除きたいのですが、どのように記述するのが正しいでしょうか?
870デフォルトの名無しさん:2011/02/06(日) 14:21:11
>>869
ワークシートの数式とVBAとを完全に混同しているのはわかりました
=Trim(A1)ってA1に入れたら循環参照しますよ?
1セル内に式と値を別々に入れることは出来ないでしょ

その内容でAutoFillが出てくるのはおかしいですね
今シート内の各セルには何かしら値があってその全セルの値にトリムを適用したいんですよね?

オートフィル使うと元々あった値の事はきれいさっぱり捨て去ります
シート全域の元の値を消し去る事になるはずですが、それでいいですかね?

おそらく各セルごとにTrimしたいんでしょうから、
この場合1セルずつ順番にTrimして回る必要があります
オートフィルのようにいっぺんには出来ませんし、
エクセルも助けてくれないので自力でコードを書く必要があります

Dim TargetCell
For Each TargetCell In ActiveSheet.UsedRange
  TargetCell.Value = Trim(TargetCell.Value)
Next

ノーチェック、動作無保証。
で、ここは一応プログラマーのスレですので
もし「For文って何ですか?」レベルだったら出直して下さいませ
配列で処理したほうがずいぶん早いでしょうが、そんな話してもしょうがなさそう
871デフォルトの名無しさん:2011/02/06(日) 15:56:54
演算子を変数で置いて数式の中で使用することってできないですか?

op = +
nf = 1 op 3

こううだとエラーになります
872デフォルトの名無しさん:2011/02/06(日) 16:07:45
>>871
オペレータへの介入はVBAでは無理です

VB7より新しいVBならバージョンによって可能ですが、
VBAはVB6を祖とする(内部バージョンはVB6.1〜VB6.5)ものです
言語仕様は10年前のままで、オペレータに関しては何も介入出来ません
873デフォルトの名無しさん:2011/02/06(日) 16:16:54
>>872
そうだったのですか
ありがとうございました
874デフォルトの名無しさん:2011/02/06(日) 16:21:25
>>871

Sub test()
Dim plus As String
plus = "+"

MsgBox Evaluate(1 & plus & 2)
End Sub
875デフォルトの名無しさん:2011/02/06(日) 16:29:43
あ、それありましたねw
彼への答えはそっちが適当なのかも
「何も」は言い過ぎでした
876865:2011/02/06(日) 16:51:18
>>870
できなかったです。

なぜセル全部にtrim関数を宛がうことがむずかしいのか私には理解できません。
よく使う処理であろうに。

勉強しなおしてきます。ありがとうございました
877デフォルトの名無しさん:2011/02/06(日) 17:16:43
>>876

横レスですが、
状況がよく分からないので
適切なうまく動かないSampleを作成して、
どこかにUpしてもらえませんか?

878デフォルトの名無しさん:2011/02/06(日) 18:50:35
>>876
できなかったですか、よくわかりませんがすいませんでした
いや難しくはないですよ。きっと造作もないです。ただ求めてる結果がわかんないです
(「ダメでした」だけじゃ何が起きたかすら分かりませんし)

> 〜よく使う処理であろうに
VBAはマクロ言語にしては異常なほど強力で、そのわり簡単だと思いますが、
逆にプの字も知らない人がほいほい扱える代物でもないです
無免許で突然ミッション車をうまく運転出来たならたいしたもんですよ
最初は誰だってそんなもんです
879デフォルトの名無しさん:2011/02/06(日) 19:16:29
一行目に列タイトル、二行目以下A〜Fに数字が入っている表があります。
この票で「@A〜F内の数値の最小値」と「A最小値の列タイトル」をG/H列に表示したいです。

@についてはMIN(AX〜FX)(Xは行番号とする)で求められたのですが
Aの@で抽出された最小値の1行目(CXが最小値なら、C1を返したい)の求め方が判りません。

アドバイスいただけると嬉しいです。
880デフォルトの名無しさん:2011/02/06(日) 19:41:07
>879
ここはExcelVBAのスレです。計算式のことは
Excel総合相談所 95
http://hibari.2ch.net/test/read.cgi/bsoft/1293162589/l50
へどうぞ
881879:2011/02/06(日) 19:42:21
>>880
早速誘導ありがとうございます、そちらのスレで再質問します。
スレ違い失礼しました。
882865:2011/02/06(日) 20:14:40
ご回答ありがとうございます。情報の小出しになってしまい申し訳ありません。

ttp://www1.axfc.net/uploader/Sc/so/202350.zip

サンプルを用意させていただきました。
いくつかのセルにスペースでの空白が入ってしまっています。
セルの数が多く一つ一つ消すには時間がかかってしまいます。
なので、全てのセルに=trim関数を適用させたいと思っています。
セルの数は毎回変わってしまうので自動で宛がってくれるVBAを組みたい
といった形です。度々申し訳ございませんがよろしくお願いします
883デフォルトの名無しさん:2011/02/06(日) 20:35:37
>>882
A1セルの#N/Aで引っかかるみたいなので、
>>870 のコードを改変して

Dim TargetCell
For Each TargetCell In ActiveSheet.UsedRange
 If Not IsError(TargetCell.Value) Then
  TargetCell.Value = Trim(TargetCell.Value)
 End If
Next

で、どうでしょうか?
884865:2011/02/06(日) 21:34:54
>>883
ありがとうございます。完璧でした。

完全に勉強不足でした。
本当にありがとうございました
885デフォルトの名無しさん:2011/02/06(日) 23:06:34
>>882,884
見返すといろいろボケたレスしてました、申し訳ないです。徹夜明けで失礼しました
循環参照〜とAutoFillの話は忘れて下さい(シートコピー部分を見落とし)
お詫びに元コード>>869へのアドバイスを上げときます

1)変数の宣言が数値型になってる
 アドレス(文字列)を代入出来ないためエラーになります。正しくは As String

2)Address(0,0)が適当
 引数を指定しないと$付きの絶対参照になります。今回の場合はフィル目的なので相対参照でないと

3)シート名が「シート1」以外だと失敗
 大量に処理するならシートごとにNameプロパティから取得すべきかも

4)問題はないですがRangeは指定方法が幾つかあり、文字列での指定以外にもRangeオブジェクトでも指定出来ます
また引数2つで「Range(左上セル,右下セル)」という指定も出来ます。例えば範囲A1:F10のセルを指定するには、
  Range("A1:F10")
  Range("A1", "F10")
  Range(Cells(1, 1), "F10")
  Range("A1", "F10")
 などなど。よって Range("A1:" & endcell) の部分は
  Range("A1",Selection.SpecialCells(xlCellTypeLastCell))
 とSpecialCellsを直接渡してしまう事も出来ます。
 が、分かり難くもなります。都度その場に応じた分り易く短い指定法を選びます

5)オートフィル
 一度の操作で両方向にフィルはできません。(マウス操作時と同じです)
 範囲をフィルする場合は上下方向、左右方向に分けて2回実行します
886デフォルトの名無しさん:2011/02/07(月) 09:29:57
指摘漏れててる
AutoFillはSelectionからじゃダメよ
いちいちセル範囲選択したくねーだろw
887デフォルトの名無しさん:2011/02/07(月) 17:22:10
Excel2003には読み上げ機能があるので、これを利用して「英会話の数字の聞き取り」に特化した訓練マクロ(下記)をつくりました。
でも問題点があります。
Excelでは、4けたの数字は年代のように2けたごとに発声する方法(1456をfourteen fifty-sixと発話)になっていて、通常の方法(1456はone thousand four hundred and fifty-six)でしゃべってくれません。
これを改善するにはどうしたらよいでしょうか?

Sub Number()
Dim a As Long
Dim b As Integer
Dim c As Integer
a = Int(Rnd * (10 ^ Int(Rnd * 5 + 3))) + 1
b = Int(Log(a) / Log(10)) + 1
c = Int(Rnd * b) + 1
Range("a1") = Int(a / (10 ^ (c - 1))) * 10 ^ (c - 1)
Range("a1").Speak
End Sub

ちなみに上記のように複雑になってるのは、下記の点を工夫したためです
(1) 日常でよく使う小さいけた数の出現頻度を多くする(最大で7けた)
(2) 日常生活ではけたの多い数は概算で使われることが多いので、それに対応。(2456231のような1の位までの細かい数字ではなく、2450000のような日常的な数字の頻度をかなりあげる)
(3) でも、たまには1の位まで細かい数字(2456231みたいな)も出題する。
888デフォルトの名無しさん:2011/02/07(月) 17:46:06
>>887
状況がよく分からないので教えてください。

・シートに、例えば[もう一度]とか[次の問題]とかのボタンが貼り付けてあるのでしょうか?
・初めからA1セルに数字を表示するのですか? それとも[答え]などのボタンを押すと表示するのでしょうか?

どうせ考えるのなら、なるべく>>887さんのイメージに近い状態で考えたいので。
インタフェイスだけでも作って考えている仕様と一緒にどこかにUpしてもらえませんか?
889888:2011/02/07(月) 17:53:06
>>887
追加。
シートを使う意味が分かりません。
フォームの方がいいような気がします。
890デフォルトの名無しさん:2011/02/07(月) 17:57:00
>>888
なるほど、インターフェイスがあると便利ですね
でもわたしは実はVBAの特にフォームを使ったインターフェイスはさっぱりわからないんです。
確かに[もう一度]とか[次の問題]とか[答え]のボタンがあると超便利って感じですよね。

あと、これはドリル練習なので大量の問題を一気に解くと力が尽きそうなので
繰り返し処理が必要ですね。まだそこらへんも含め全く考えていませんでした。
891デフォルトの名無しさん:2011/02/07(月) 18:01:34
>>887
速度どうでもいい所でLogとか使ってると嫌われるよ
自力で数式を解決出来ないならなお更だよ…
孤高のプログラマー気取るのもいいけど
他人に質問するなら読みやすさも考えてくれよ

普通に考えて、入力数値を文字に置き換えて
前方からいくつか拾ってそれを対象に処理すればいいのにと思った
7桁の数なんだから文字列に置き換えても高々数バイトなんだし…
Randは(1)を実現するためのIf文に使おうよ

あとは出来上がった数値文字列を1文字ずつ処理して
「one thousand four hundred and fifty-six」等の英文を生成して
それを読み上げさせればいいんじゃない?
892デフォルトの名無しさん:2011/02/07(月) 18:10:00
>>890
それでは、インターフェイスはとりあえず私なりに考えてみます。
飽きるか疲れたら止めますけど、途中でもできたところまではお見せします。
893888:2011/02/07(月) 21:02:11
>>890
テスト不十分ですが、
http://www1.axfc.net/uploader/Sc/so/202690
キーワードは888
894888:2011/02/07(月) 22:12:54
895890:2011/02/07(月) 22:14:30
>>888
すばらしい!!
ありがとうございます。
いまダウンロードしたばかりで少し使ったばかりですが
ものすごく見やすく使いやすいです。
まるで魔法みたいなツールですね。

あとは、この訓練は大量にやることに意味があるので
大量に解くときの使い勝手のよさ(例えばマウス操作をしないで、数値→Enter→数値→Enter→数値→Enter→・・・だけの操作で瞬時に次の問題にうつれるみたいな)
を考慮したいところです(自分には無理ですが)。
896888:2011/02/07(月) 22:32:36
>>895
カーソル移動用のコード追加です。
宣言セクションに
Const KEY_ENTER As Integer=13 'EnterKeyのKeyCodeは13

'フォーカス移動用
Private Sub AnswerTextBox_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, Byval Shift As Integer)
If KeyCode.Value = KEY_ENTER Then
Call AnswerButton_Click
End If
End Sub

897890:2011/02/08(火) 00:04:36
>>896
ありがとうございます。
これで格段に使いやすくなりました。

すでに練習をしまくってますが
コツがわかってきて、thousandを聞いたらすぐにそれをコンマ( , )に脳内で変換し、
常に3ケタの数字を固まりとして脳にイメージすればいいことがわかりました。

よし、English板でもこのツールをみんなに紹介しようかな。
898888:2011/02/08(火) 00:45:03
>>897
あと、
AnswerButton_Click()のプロシージャの最後に、
QuestionButton.SetFocus
の一文を入れた方が使いやすいかも知れません。

タブオーダーについても、
出題→もう一度→解答欄→答えを見る→出題
と時計回りにした方が使いやすいかも知れません。
その人の使い方によるでしょうけれど。
899888:2011/02/08(火) 00:59:56
>>897
1桁の数字の出題率を0にしても、たまに1桁が出題されるバグ修正

問題作成のプロシージャ内の
Randomizeの下の
n = Rnd * denom を
n = Int(Rnd * denom) に
修正してください。
900デフォルトの名無しさん:2011/02/08(火) 16:46:56
コンボボックスの項目がいくつあるか知る方法はどうすれば良いですか?
With Me.Combobox
 .AddItem "a"
 .AddItem "b"
 .AddItem "c"
End With
この場合は3

With Me.Combobox
 .AddItem "a"
 .AddItem "b"
End With
この場合は2を取得したいです
901900:2011/02/08(火) 17:44:26
すいませんageます
902デフォルトの名無しさん:2011/02/08(火) 18:41:15
Sort メソッドの昇順/降順を、プロシージャ-の引数で指定したいのですが可能ですか?
その場合、データ型と呼び出し側の定数値は、どのようにすればよいのでしょう?
903デフォルトの名無しさん:2011/02/08(火) 18:47:55
>>900
Combobox1.ListCount
904デフォルトの名無しさん:2011/02/08(火) 18:59:28
>>902
定数は列挙型だからInterger型を使う

Dim so As Integer
so = xlAscending  ' ソートのオーダー
Range("A1:A5").Sort Key1:=Range("A1"), order1:=so
905デフォルトの名無しさん:2011/02/08(火) 19:37:31
おまいらExcel2007のソートのコーディングできる?
俺は記録マクロを頼りにしないとできない。
906デフォルトの名無しさん:2011/02/08(火) 22:46:49
初歩的ですが誰か教えてください。

セル値(文字列)を数値に変換したいのですが、
数字以外の文字が入っているとエラーになると思います。

そこで、数字(0〜9)以外の文字が入っていたら
その文字を消したいのですがどのようにすればよいでしょうか?

例. aw971d24h → 97124 

replaceやsubstituteで簡単にかけるのでしょうか?
907デフォルトの名無しさん:2011/02/08(火) 23:10:27
908890:2011/02/08(火) 23:26:29
>>888
ありがとうございます。ちょっと試してみます。
VBAでこんなことまでできるとはすごいです。
909デフォルトの名無しさん:2011/02/09(水) 00:42:11
住所録の中から、いくつかの特定の住所の場合はその行の空欄のセルに△をいれるというVBAを作りたいのですが、
特定の住所というのが、住所1、住所2、住所3・・・と50個くらいあります。
延々と一つ一つ指定していくしかないでしょうか?
できるだけ簡潔に書きたいのですが
910デフォルトの名無しさん:2011/02/09(水) 00:55:15
>>909
Forを使いましょう
911906:2011/02/09(水) 00:56:01
>907

できました!ありがとうございます!
とてもわかりやすかったです。
912デフォルトの名無しさん:2011/02/09(水) 01:19:00
>>909
例えば、
sub test()
const C as integer = 1 '住所のいくつ右のセルに△を入れるか
dim s,t 'ループ用
for each s in range("住所録")
 s.offset(,c).value=""
 for each t in range("特定住所リスト")
  if s.value like "*" & t.value & "*" then
   s.offset(,C).value="△"
   exit for
  end if
 next
next
end sub
913デフォルトの名無しさん:2011/02/09(水) 23:32:53
本日からVBAをさわり始めた超初心者です。

セルB4〜B6が全て空白でなかったらメッセージを出したいのですが、
下記のように記入し実行すると「実行時エラー 型が一致しません」
とエラーが出てしまいます。

If Range(Cells(2, 4), Cells(2, 6)).Value <> Empty Then

"セルB4〜B6が全て空白でなかったら"という条件を作るにはどうしたら良いのか?
どなたかご教示ください。
914デフォルトの名無しさん:2011/02/09(水) 23:40:21
>>913

Sub check_blank()

 Dim r As Range
 Dim allBlank As Boolean

 With Sheet1
  allBlank = True
  For Each r In Range(.Cells(2, 4), .Cells(2, 6))
   If Trim(r.Value) <> "" Then
    allBlank = False
    Exit For
   End If
  Next
 End With
 
 If allBlank Then
  MsgBox "全部空白!"
 Else
  MsgBox "全部空白じゃない!"
 End If
 
End Sub
915デフォルトの名無しさん:2011/02/09(水) 23:41:10
Rangeの前に . 入れるの忘れた。動くけど。
916デフォルトの名無しさん:2011/02/09(水) 23:59:42
>>913
それは、別にVBAに限らず、例えば、3年2組の身長は何cmですか? 
と尋ねているようなものだと思います。
組の身長を尋ねた場合、どう答えるのか? というルールが決まっている場合を除いて、
(例えば、組の身長を尋ねられたら、平均の身長を答えるとか)
普通は、○年○組のAさんの身長は何cmですか?
のように尋ねると思います。その場合、答えることが許可されていたら、
170cmです。と答えるでしょう。

すなわち、"セルB4〜B6が全て空白ではなかったら" という条件は、
セルB4は空白でないか、もしくは、セルB5は空白でないか、もしくは、セルB6は空白でないか、
と条件を立てるといいです。
Cells(2,4).Value <> Empty Or Cells(2,5).Value <> Empty Or Cells(2,6).Value <> Empty

慣れれば、>>914のように繰り返しを使えると良いです。
917916:2011/02/10(木) 00:03:33
>>916
行と列が逆だ。>>913
B4からB6なら
Cells(4,2).Value <> Empty Or Cells(5,2).Value <> Empty Or Cells(6,2).Value <> Empty
918デフォルトの名無しさん:2011/02/11(金) 01:38:13
最近、気づいたんだが、イベントプロシージャ単独、もしくはFSOオブジェクトを併用したら、マクロウイルスを作ること可能だよな?
919デフォルトの名無しさん:2011/02/11(金) 08:57:34
スレ汚すな
920デフォルトの名無しさん:2011/02/11(金) 10:21:44
↑おまえ粕。イベントプロシージャについて述べてるだけやん。
921デフォルトの名無しさん:2011/02/11(金) 11:05:38
10年以上も昔の話をされてもなあ……
そんな方法は誰も引っかからなくなって廃れたんだよ。
922デフォルトの名無しさん:2011/02/11(金) 12:14:02
2003つかってます。
UserFormを操作しているときに押されたキーを取得したいときは
すべてのオブジェクトにkeypressイベントを記述しなければならないのでしょうか。
たとえば、UserForm_KeyPressなどですべて受け取れるようにはできませんか?
923デフォルトの名無しさん:2011/02/11(金) 13:11:41
>>922
UserForm_KeyPressは非常に限られた状況でしか使えないので、
フォーム対するキー入力をまとめて処理したい時はAPIを使う
924デフォルトの名無しさん:2011/02/11(金) 15:44:08
複数のブックを一つのブックにまとめるvbaを組んでいます。


----------------------------------------------
Sub TEST01()
Dim myObj As Object
Dim myDir As String, myFle As String
Dim ws As Worksheet, mb As Workbook, wb As Workbook
Set myObj = CreateObject("Shell.Application"). _
BrowseForFolder(0, "フォルダを選択してください", 0)
If myObj Is Nothing Then Exit Sub
If myObj = "デスクトップ" Then
myDir = CreateObject("WScript.Shell").SpecialFolders("Desktop")
Else
myDir = myObj.Items.Item.Path
End If
Application.ScreenUpdating = False '画面更新を一時停止
Set mb = ThisWorkbook
myFle = Dir(myDir & "\*.xls*") 'フォルダ内のExcelブックを検索
Do Until myFle = Empty '全て検索
If myFle <> ThisWorkbook.Name Then 'ブック名がこのブックの名前でなければ
Set wb = Workbooks.Open(myDir & "\" & myFle) 'そのブックを開きwbとする。
wb.Worksheets(1).Copy After:=mb.Sheets(mb.Sheets.Count) '1枚目のシートをコピー
Set ws = mb.Sheets(mb.Sheets.Count)
ws.Name = wb.Name '名前をwbのBook名に
wb.Close (False) 'wbを保存しないで閉じる
End If
myFle = Dir 'フォルダ内の次のExcelブックを検索
Loop '繰り返す
Application.ScreenUpdating = True '画面更新一時停止を解除
End Sub
----------------------------------------------
925924:2011/02/11(金) 15:44:50
>>924
というVBAです。
しかしエラーがでます。エラー内容は
------------------------------------
実行時エラー'1004':
Worksheet クラスのCopyメソッドが失敗しました。
------------------------------------------

なにが間違っているかわかりません。お願いします
926デフォルトの名無しさん:2011/02/11(金) 18:16:35
遅延バインディング
927924:2011/02/11(金) 21:09:46
ダメだできない…

フォルダにある全てのbookを一つのbookにまとめる。
シート名が被っている場合は自動で名前を変える
(book1に東京シート、book2にも東京シートがあった場合はどちらかを東京シート(2)にするなど。)

これが作れないせめてヒントだけでも…お願いします
928デフォルトの名無しさん:2011/02/11(金) 21:18:34
>>924
とりあえずブックをUpしてください。
お互いの時間の節約のために。
929デフォルトの名無しさん:2011/02/11(金) 21:28:16
wbがactiveになっていない
930デフォルトの名無しさん:2011/02/11(金) 21:30:22
>>924
とりあえず試したら正常動作しました

一つ考えられるのは、多量のデータがあって問題があるのかも?

毎回、コピー終了後にセーブしたら動くかも?
931924:2011/02/11(金) 22:13:11
>>928
http://www1.axfc.net/uploader/Sc/so/204120.zip
アップロードさせていただきました。
1.xls 2.xls 3.xls 3つをこういう形にしたい.xls
の4点が入っています。
932デフォルトの名無しさん:2011/02/11(金) 22:55:31
>>931
拝見させていただきました。
やっぱり>>924のコードから想像したのとかなり違いますね。
>>927の件はExcelが自動でしてくれと思います。
私は、こうしてみましたけど、どうでしょうか?

   Set wb = Workbooks.Open(myDir & "\" & myFle)
   Call addSheetAll(mb, wb) 'ワークブックmb に ワークブックwbのシートを全てコピー
   wb.Close(False)
...
Sub addSheetAll(mb As Workbook, wb As Workbook)
 Dim i As Integer
 For i = 1 To wb.Worksheets.Count
  wb.Worksheets(i).Copy after:=mb.Sheets(mb.Sheets.Count)
 Next
End Sub
933924:2011/02/11(金) 23:49:31
>>932
わざわざありがとうございます。
しかしダメでした。
------------------------------------
実行時エラー'1004':
Worksheet クラスのCopyメソッドが失敗しました。
------------------------------------------
とエラーがでます。

wb.Worksheets(i).Copy after:=mb.Sheets(mb.Sheets.Count)

ここがダメみたいです。
934デフォルトの名無しさん:2011/02/11(金) 23:56:37
>>924のコード、新規ブックにコピーして動く事は動いたのだけれど
そちらの状況が判らないです

一つもコピーできなかったのか、それとも幾つかはコピー出来たのか

バージョン情報なども聞きたいところです
935932:2011/02/12(土) 00:03:02
>>933

>>931のサンプルで試してみたのですが…
931のサンプルでもエラーがでますか?

それとも別のブックでエラーがでるのでしょうか?
936924:2011/02/12(土) 00:10:33
バージョンは
Microsoft Office Excel 2007(12.0.4518.1014) MSO(12.0.4518.1014)

1.xlsの3つのシートはコピー完了しています。
それから>>933のエラーがでます。

もちろんアップロードしたサンプルで動くか検証しています
937デフォルトの名無しさん:2011/02/12(土) 00:14:29
シートの名前が同じとか?
938932:2011/02/12(土) 00:19:28
>>936
私の環境では困ったことに>>932のコードでエラーがでないんですよね。
一度試してみてもらえませんか?
http://www1.axfc.net/uploader/Sc/so/204184
キーワードは932です。
939924:2011/02/12(土) 00:32:56
>>938
ありがとうございます。やはりダメでした。
940932:2011/02/12(土) 00:33:34
>>924
あと、http://support.microsoft.com/kb/210684/ja
の解決方法は試してみましたか?
941932:2011/02/12(土) 00:52:36
>>933
>>932のコードの
For i = 1 To wb.Worksheets.Count

wb.Worksheets(i).Copy after:=mb.Sheets(mb.Sheets.Count)
の間に、
Debug.Print wb.Name, i, wb.Worksheets(i).Name
Debug.Print mb.Name,mb, Sheets(mb.Sheets.Count).Name
Debug.Print
と入力して実行したら、
イミディエイトウィンドウにどのように出力されますか?
942924:2011/02/12(土) 01:41:16
>>940
ありがとうございます。解決はできませんでしたが、
別PCのexcel2003を使ったところ>>932のコードで動かすことができたので満足です。
本当に感謝です!ありがとうございました
943デフォルトの名無しさん:2011/02/12(土) 07:40:39
>>942
横槍だけど、動かない環境で >>941 試してあげてよ。
せっかく >>932 があれこれやってくれたんだからさ。
944デフォルトの名無しさん:2011/02/12(土) 14:25:32
せつねぇ
945デフォルトの名無しさん:2011/02/12(土) 17:18:11
勝手に教えたがりやってんだから、放置されたからって粘るなや
946デフォルトの名無しさん:2011/02/12(土) 18:32:13
>>924のコードで疑問点あり

>myFle = Dir...
>Do Until myFle = Empty

Dir関数ではファイルがなくなった(ない)場合は
myFle="" (長さ0の文字列)が戻ると思っていたんだが
上記のmyFle=Emptyでもちゃんと動作するのはなぜだ?
だれか説明してくれぃ。。
 


947デフォルトの名無しさん:2011/02/12(土) 19:32:31
VarCmpでVT_EMPTYとVT_BSTRの長さ0のVARIANTを比較すると
VARCMP_EQが返されるから、とか言ってみる。

VBAの世界では、Emptyと長さ0の文字列は同じものと位で
考えておけばいいんじゃないかと。
948デフォルトの名無しさん:2011/02/12(土) 19:39:34
>>946
> Dir関数ではファイルがなくなった(ない)場合は
> myFle="" (長さ0の文字列)が戻ると思っていたんだが

その認識で正しいみたい。
http://msdn.microsoft.com/ja-jp/library/dd313953.aspx

>上記のmyFle=Emptyでもちゃんと動作するのはなぜだ?

myFile = Empty で比較するときに、両辺を文字列型に変換して比較するから
Empty が "" に変換されるんじゃね。
949デフォルトの名無しさん:2011/02/12(土) 19:50:28
emptyをstringに入れたときにどう暗黙変換されるかの問題だ。
950946:2011/02/12(土) 22:29:15
回答、ありがと。
VBAについてはそこそこ知ってるつもりだったが
Emptyキーワードは、Variant型変数でしか使えんと思っとった
で、投稿した後、ちょこっとテストしてみたところ、

Empty → 数値型    → 0
Empty → 文字列型   → 長さ0の文字列

として処理されてるようだな
今回は勉強になった、回答くれた皆に感謝!
 
951デフォルトの名無しさん:2011/02/12(土) 22:39:45
Do Until myFle = Emptyなんてのはなんかいやだねぇ
ところでおまいらTextBoxやComboBoxの未入力時のTextプロパティはvbNullStringと比較してる?
952デフォルトの名無しさん:2011/02/13(日) 11:32:22
on Error Resume Next 難しいな
使わずに書こうと思ってたんだけど、使わないとどーしても避けれない処理がある
Range.Pastespecial を使うときに

 on error resume next
 range.pastespecial
 on error goto 0

ってon error で囲まないとエラー時の対応が出来ない(解らない)
どーしたもんか・・・
953デフォルトの名無しさん:2011/02/13(日) 11:44:20
open とかのファイルを扱う際のエラー処理にも必須だと思うが...。

> どーしたもんか・・・

書いてる通り on error で囲むだけだろ?
何が難しいのか、理解するのが難しいよ (w
954デフォルトの名無しさん:2011/02/13(日) 12:25:24
一つの元データのあるブックから、複数のブックにデータを
コピーしたいのですが、

Sub A08管理図の入力()

Dim OpenFileName As String 'ファイルオープン
Dim 転記元 As Workbook, 転記先 As Workbook
MsgBox "最初の管理図を開いてください"
ChDrive "D"
ChDir "D:\結果"
OpenFileName = Application.GetOpenFilename("Microsoft Excelブック,*.xls?")
If O <> "False" Then
Workbooks.Open OpenFileName
Else
MsgBox "キャンセルされました"
Exit Sub
End If
Set 転記先 = ThisWorkbook
転記先.Worksheets("確認").Select

としているのですが、
[ 転記先.Worksheets("確認").Select ]
のところで実行時エラー’9’
が出ます。
転記先のシートが複数あるのでそれぞれ選択するにはどうすればよろしいでしょうか?

ここで躓いて先に進めません。
955デフォルトの名無しさん:2011/02/13(日) 12:58:24
>>951
Trim かけて "" と比較するのがよくない?
大したコストじゃないでしょ。
956デフォルトの名無しさん:2011/02/13(日) 13:05:31
>>954
まず、エラーについて

元データブックを開いた段階で、転記先ブックがアクティブじゃなくなる

従って

Set 転記先 = ThisWorkbook
転記先.Activate
転記先.Worksheets("確認").Select

とする

次に複数のシートを選択するには、SelectのオプションReplaceを指定する

Worksheet オブジェクト.Select(Replace)

以下、Replaceについての引用
(シートでのみ使用) 既に選択しているオブジェクトの選択を解除して、
指定したオブジェクトのみを選択するには、True を指定します。
既に選択しているオブジェクトに加えて、指定したオブジェクトを選択するには、False を指定します。
957954:2011/02/13(日) 13:32:28
>>956さん
私の書き方が悪く申し訳ありません。
転記元ブックはもともと開いており、このコードを記述しています。

[OpenFileName = Application.GetOpenFilename("Microsoft Excelブック,*.xls?") ]
で開くのは転記先ブックです。

いま見直して気付いたのですが、[Set 転記先 = ThisWorkbook]
が間違っているとおもうのですが、どう修正したらよいでしょうか?

Worksheets("確認")は後から開いた転記先ブックにあり、

Set 転記先 = OpenFileName
転記先.Activate
転記先.Worksheets("硬質").Select

としてもエラーが出ました。

958デフォルトの名無しさん:2011/02/13(日) 14:42:46
>>951

If TextBox1.Text = "" Then

これじゃ拙いのか?
もしそうなら理由を請う!
 
959956:2011/02/13(日) 17:44:41
>>957
もう解決してるかもだけど

If OpenFileName <> "False" Then
Set 転記先 = Workbooks.Open(OpenFileName)
Else
MsgBox "キャンセルされました"
Exit Sub
End If

で、いいかなと

デバッグとかの使い方を練習した方が良いかと思う
960954:2011/02/13(日) 17:58:34
>>959
上手くいきました。ありがとうございました。

おっしゃる通りまだまだ勉強不足なので精進します。

助かりました!
961デフォルトの名無しさん:2011/02/13(日) 18:58:18
>>958
色々Bingってみたりしたけど、結論としては、
vbNullStringは、ポインタに変換すると必ずNULLになる空文字列、
って感じっぽいな。
つまり、文字列として扱っている分には、""と全く変わらない。
""がポインタに変換された時、必ずNULLにならないかどうかは知らん。
962デフォルトの名無しさん:2011/02/13(日) 19:11:44
TextBoxやComboBoxは未入力時は長さ0の文字列じゃなく値0の文字列を返すから
If TextBox1.Text = vbNullString Thenがベターではある。
If StrPtr(TextBox1.Text) = 0 Thenでもよいが。
963デフォルトの名無しさん:2011/02/13(日) 19:52:00
プログラムかいてると、
人間の判断力ってすげぇ
って思えてくる
964デフォルトの名無しさん:2011/02/13(日) 21:07:08
>>962
>TextBoxやComboBoxは未入力時は長さ0の文字列じゃなく値0の文字列を返す
これをはっきり示した資料あるか?

TextBox1.Textなんかだと、""代入してもvbNullStringになるっぽいが、
普通の文字列変数だとそうならないみたいだな

VBAでは通常NULLストリングとNULLポインタの区別をする必要はないんだし
API呼び出し等で明示的にNULLポインタである必要がある場合以外、vbNullStringは
使わない方がいいと思うが
965958:2011/02/13(日) 23:51:07
確かにstrptrでは0になるな

ただ、
TextBox1.Text = ""
TextBox1.Text = Empty
TextBox1.Text = vbNullString
これがみなTrueになるわけだから、
今回のことは知識として頭にいれとく程度でよさそうだな

それに、>>964も言っとるように、
またヘルプにも書いてあるように
vbNullStringは外部プロシージャの呼び出しで使うのがええような。。

何れにしろ、またまた勉強になった、ありがとな
966デフォルトの名無しさん:2011/02/14(月) 20:02:06
web上にあるファイルをダウンロードするのに何かないかなと思って
探したらURLDownloadToFileというのがあって使ってみたんだけど

URLDownloadToFile(0, "https://www.abc.com/123.xls", "c:\", 0, 0)

プロトコルがhttpならOKなんだけど、httpsでsslが入るとダメ。
これって何かいい解決方法はないでしょうか?

それともVBAでhttpsでファイルを落とすのは無理?
分かる方是非教えてください!
967デフォルトの名無しさん:2011/02/14(月) 21:28:34
>>966
MSXMLを使えば可能
968デフォルトの名無しさん:2011/02/14(月) 21:46:56
>>967
ありがとございます!
ちょっと調べてみたのですが

Dim objHttp as Object buf As String
Set objHttp = CreateObject("MSXML2.XMLHTTP")
objHttp.Open "GET", "http://www.abc.com/123.xls", False

こんな感じのコードで上のコードで「http」の部分が「https」でも
OKということでいいでしょうか?
ちょっと今実行環境がないので。。。
ありがとございます!
969デフォルトの名無しさん:2011/02/15(火) 11:55:32
ユーザーフォーム内でenterキーにhogeボタンを押したときと同じ動作をさせたいです
ググりながらやってみましたが何か根本的に間違ってるような気がしてきました
どうしたらいいのでしょうか?

Sub UserForm_Initialize()
   Application.OnKey "{Enter}", "hoge_Click"
End Sub

Sub hoge_Click()
   xxx
End Sub
970デフォルトの名無しさん:2011/02/15(火) 12:32:44
>>969
そのフォームの中にボタンが一個だけで、他に入力や選択を行うコントロールが一つもなければ
何も書かなくても自動的にEnter=ボタンクリックになる

あと、Application.OnKeyはEnterには使えない仕様
971デフォルトの名無しさん:2011/02/16(水) 09:22:58
>>970
enter以外を割り当てても反応しないので諦め、
ttp://okwave.jp/qa/q4178922.htmlで紹介されている方法は理解を超えていたので
Acceleratorプロパティで我慢することにしました
どうもありがとうございました
972デフォルトの名無しさん:2011/02/16(水) 18:19:07
もしスレチだったらすみません。

accessのVBAからADOでexcelに
データを書きだしているのですが、
文字列扱いの数字にエラーインジケータが
ついてしまいます。
これをVBAで解除することは
できるのでしょうか?
973デフォルトの名無しさん:2011/02/16(水) 20:08:04
>>972
最初からエラーチェックをしない設定には出来ないの?
974デフォルトの名無しさん:2011/02/16(水) 20:22:28
Excelのヘルプで『エラーインジケータ』を見ると
色々出ていると思う

ただ、データのコンバージョンでエラーが出た場合、
一応、すべて目を通さないとひどい目にあうかも?
975972:2011/02/16(水) 21:28:36
>>973
表示の有無設定ってツールオプションで行うので
ユーザの環境によって変わると思ってたんですけど
認識違いですかね?

>>974
ありがとうございます。
一度ヘルプも確認してみます。
976デフォルトの名無しさん:2011/02/18(金) 20:55:48
VBAもいいかげんアップデートしてくれないものか
せめて構造化例外とオーバーロードを・・・
977デフォルトの名無しさん:2011/02/18(金) 23:25:57
GetOpenFilename等でユーザーが指定したファイルのパスをUNCパスに置き換える方法を教えてください。
自分ではパワーシェル等でネットワークドライブの一覧を取得して
割り当てられているドライブ名をコンピュータ名に置き換えるという方法しか考えつかなかったのですが、
それ以外に何かやり方はないでしょうか?
978デフォルトの名無しさん:2011/02/19(土) 00:50:28
>>977
このへんが参考になるかな?
ttp://support.microsoft.com/kb/160529/ja
979デフォルトの名無しさん:2011/02/19(土) 08:57:23
IF文で判定させたいのですが、変数 i が
60から55、55〜50のような感じで条件をだしてマクロを組んで見たのですが
上手く判定してくれません。

Dim i AS Integer

i = Range("A1").Value
If 60 >= i > 55 Then
Range("B1").Value = "A"
ElseIf 55 >= i > 50 Then
.Range("B1").Value = "B"
END IF

どうしたら判定してくれるのでしょうか??

980デフォルトの名無しさん:2011/02/19(土) 09:17:51
977です
978>>
ありがとうございます!リンク先読んできました。
あるユーザーが指定したファイルを複数人で使う想定だったので
個人の環境に依存するネットワークドライブ名を使いたくなかったんです。
おかげさまでできそうです!
981デフォルトの名無しさん:2011/02/19(土) 09:32:47
リンクミスった
>>978さんありがとうございました!
982デフォルトの名無しさん:2011/02/19(土) 09:35:26
>>979
If (60 >= i) And (i > 55) Then
983デフォルトの名無しさん:2011/02/19(土) 10:00:34
>>982
上手く判定してくれました。
早いレスありがとうございました。

984デフォルトの名無しさん:2011/02/19(土) 16:02:02
エクセル2002を使ってます。

あるセルの値をクリアしたら、その行のZ列の値もクリアしたいのですが、

Dim jissibiRow As Integer
If Target.Value = "" Then 'あるセルの値をクリアしたら
jissibiRow = ActiveCell.Row 'そのセルの行番号を出して
Range("Z" & jissibiRow).ClearContents 'その行のZ列の値もクリアする

とすると、Z列の値は消えるのですが、消えるまでに5秒程度かかってしまいます。

If Target.Value = "●" Then 'あるセルに●を入力したら(実際はプルダウンで入力)
jissibiRow = ActiveCell.Row 'そのセルの行番号を出して
Range("Z" & jissibiRow) = "実施済み" 'その行のZ列に実施済み"と表示

の場合は直ぐに実施済みと表示されるので、セルをクリアした場合の判定が間違っていると
思うのですが、どのようにすればよろしいのでしょうか?
985984:2011/02/19(土) 17:15:15
>>984です。
少し状況が変わってきました。

Range("Z" & jissibiRow).ClearContents を

Range("Z" & jissibiRow) = "" にしても同じように時間が掛かったのですが、

Range("Z" & jissibiRow) = " " ”と”の間に半角スペースを入れると直ぐに反応するようになりました。

何も入れないと時間がかかるということは分かったのですが、やはり何も入れたくないです。
どのように修正すればよいかアドバイスお願いいたします。
986デフォルトの名無しさん:2011/02/19(土) 18:50:55
>>985
http://codepad.org/O5beUhFS
バージョンによってはClearContentsが遅いみたいだな、使わなければいいんでないの?
987デフォルトの名無しさん:2011/02/19(土) 20:55:50.87
>>985
部分的なコードを提示しちゃだめだぞぃ
Changeイベントを使っていると思うがそれだと

1.Range("Z" & jissibiRow).ClearContents
2.Range("Z" & jissibiRow) = ""
3.Range("Z" & jissibiRow) = " "半角スペースを入れる

上記1,2,3でもZ列のChangeイベントが発生する
そして、1,2では、
  If Target.Value = "" Then
これに引っかかるからエンドレスになる
(実際はある回数で止まる)ので遅くなる

3では、If Target.Value = "" Then
 に引っかからず即終了するから早くなる

●このようにChangeイベント内でセルに値を入れたら
そのセルのChangeイベントが発生するので
それを止めるコードを追加しなといけない

Application.EnableEvents = False  '▼イベントOFF
  Range("Z" & jissibiRow).ClearContents
Application.EnableEvents = True  '▲イベントON


それから、
jissibiRow = ActiveCell.Row は
jissibirow = Target.Row  の方がベター

988デフォルトの名無しさん:2011/02/19(土) 23:35:45.10
csvを読み込んだんですが、数字として認識されません(セルの左上に緑が付きます)
「文字列のセルを数字にする」or「数字として読み込む」方法はあるのでしょうか?
989デフォルトの名無しさん:2011/02/20(日) 00:47:49.86
990デフォルトの名無しさん:2011/02/20(日) 00:49:31.80
>>987
御指摘のとおりchangeイベント使っておりました。
的確な回答ありがとうございました。
イベントを止めるコード勉強になりました。
Target.RowとActivecell.Rowの違いも調べます。

>>986
ありがとうございました。
こういうやりかたもあるのですね。勉強になりました。
991デフォルトの名無しさん:2011/02/20(日) 10:39:21.74
 
992デフォルトの名無しさん:2011/02/20(日) 17:07:39.23

次スレお願いします
993デフォルトの名無しさん:2011/02/20(日) 20:11:38.84
自分で作ったユーザーフォームを実行中に、シートをいじれる状態にするにはどうすればいいですか
今はユーザーフォームが常に最前面に出てしまい、ユーザーフォームを消さない限りシートをスクロールすることすら出来ません
994デフォルトの名無しさん:2011/02/20(日) 20:27:26.56
>>993

Showメソッドの引数に、 0 又は、vbModeless を指定する

  UserForm1.Show 0  又は、vbModeless

詳しくはShowメソッドのヘルプをみれぃ
 
995デフォルトの名無しさん:2011/02/20(日) 20:48:48.73
>>994
どうもありがとうございました
996デフォルトの名無しさん:2011/02/20(日) 23:53:43.98

落ちる前に埋め
997デフォルトの名無しさん:2011/02/21(月) 00:33:04.04
998 冒険の書【Lv=2,xxxP】 :2011/02/21(月) 01:27:39.21
lv低すぎてダメ
999デフォルトの名無しさん:2011/02/21(月) 07:15:57.90
梅三郎
1000デフォルトの名無しさん:2011/02/21(月) 07:17:56.02
ありがとう。そして、さようなら。
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。