別クラスから、メソッドを操作する【VB.NET】
タイトル通りです。
どうすれば良いのか、思いつかなかったので先輩に教えてもらいました。
Private Sub frmTest_FormClosing(sender As System.Object, _ e As System.Windows.Forms.FormClosingEventArgs) _ Handles MyBase.FormClosing '呼び出したい画面 Dim frm As frmTest = CType(Me.Owner,frmTest) 'comboboxクリア frm.cmbテスト.DataSouce = Nothing 'combobox設定 frm.cmbテスト設定(frm.cmbテスト,"") 'combobox選択名設定 frm.cmbテスト.Text = Me.strTestNm End Sub
frm.cmbテスト設定()が、メソッド名です。
呼び出したいメソッドは、スコープをPublicにします。
・・・これが思いつかなくて時間がかかりました。
DataGridのカラムを指定してデータを取得【VB.NET】
DataGridが苦手なので、少し復習します。
'カーソルを特定の1行まで移動させる For Each dr As DataGridViewRow in grdテストグリッド.Rows 'strIDには、システムIDのデータの1つが入っている If dr.Cells("テストID").Value = strID Then grdテストグリッド.Rows(dr.Index).Selected = True End If Next 'カーソルの場所までデータグリッドをスクロール grdテストグリッド.FirstDisplayedScrollingRowIndex = _ grdテストグリッド.SelectedCells(0).RowIndex
DataGridViewのColumnではなくRowを使って、データを取り出すというのが頭にしっくりきません。
忘れないように気をつけます。
似たようなコードをもう一つ。
For Each dtGrid_test As DataGridViewRow In grdテストグリッド.Rows 'NullValueエラー回避 If dtGrid_test.Cells("テストコード").Value = Nothing Then Exit For End If str_test = dtGrid_test.Cells("テストコード").Value.ToString().Trim() str_selectedvalには、インサートしようとしているデータが入っている。 If str_test = str_selectedval blCheck = False Call MsgBox("重複しています",Me) Exit Sub End If Next
日付について色々【VB.NET】
前回の記事から時間が経ってしまいました。
今回は、VB.NETでの日付変換についてです。
'和暦を日付変換することによって、正確な日付が入力されているのか確認する。 If Not DateTime.TryParse(cmb_年号.Text + txt_年.Text + "年" + txt_月.Text + "月" + txt_日.Text + "日",chkDate) Then Call MsgBox("作成を入力してください",Me) cmb_年号.Focus() Return False End If
chkDateの中には、多分こんなものの一部が入っています。
0730...chkDateは、何時何分何秒が入っているだけでした。このように和暦でも、TryParseはできるそうです。ただ、新しい和暦になるとエラーになってしまうかもしれないとのこと。(先輩談)
次は西暦から和暦の変換です。
Public Function chg_西和(ByVal str日付 As String,ByVal intフォーマット As Integer) As String '基準日の年・月・日を取得 Dim BaseY As Integer Dim BaseM As Integer Dim BaseD As Integer 'ループに使う変数 Dim cnt As Integer Dim 元号 As Integer = UBond(元号一覧) '元号一覧の中身も後で確認 '6桁なら(年月のみ)8桁にする If str日付.Length = 6 Then str日付 = str日付 + "01" ElseIf str日付 = "0" Then Return "" End If BaseY = Integer.Parse(Mid(str日付,1,4)) BaseM = Integer.Parse(Mid(str日付,5,2)) BaseD = Integer.Parse(Mid(str日付,7,2)) '戻り値初期化 chg_西和 = "" '元号の数だけループ For cnt = 0 To 元号 Step 1 With 元号一覧(Cnt) '取得した基準日と、DBにある元号開始日・終了日を比べる '開始日より基準日が大きい、かつ、基準日が終了日より小さい場合 If(Integer.Parse(.getKaisi) <= Integer.Parse(str日付) And _ Integer.Parse(str日付) <= Integer.Parse(.getSyuryo)) Then If intフォーマット = 0 Then '平成xx年xx月xx日と返す chg_西和 = .getGengoNm & _ String.Format("{0:D2}",BaseY - _ (Integer.Parse(Mid(Trim(.getKaisi),1,4))-1)) &"年"& _ String.Format("{0:D2}",BaseM) &"月"& _ String.Format("{0:D2}",BaseD) &"日"& Else If intフォーマット = 1 Then '以下、戻す値の形が変更される処理が続く End If Exit For Else If (Integer.Parse(.getKaisi) > str日付 Or _ str日付 < Integer.Parse(str日付) >= Integer.Parse(.getSyuryo)) Then MsgBox.Show("基準日が正しく設定されていません") 'For文を抜ける Exit For End If End With Next End Function
SQLでの抽出方法 【IN】【ROW_NUMBER】【副問い合わせ】
①IN
SELECT * FROM test_table WHERE aa IN (SELECT aa FROM (SELECT aa FROM test_table GROUP BY aa,bb,cc,dd HAVING COUNT(*) >= 2) AS X) --6.28 これでもできた。 SELECT * FROM test_table WHERE aa IN (SELECT aa FROM test_table GROUP BY aa,bb,cc,dd HAVING COUNT(*) >= 2)
IN句には複数の条件を記述することができます。
このsql文では、副問い合わせを行っている・・・のですが、副問い合わせの中で同じテーブルを使用するとエラーが出てしまうので、ASで別名をつけています。
書いていて思い出しました。
そのエラーが実際出るのかを試していません。
明日会社でやってみよう。
②ROW_NUMBER
SELECT aa,bb,cc,dd ,ROW_NUMBER() OVER(PARTITION BY aa,bb,cc,dd ORDER BY aa) AS 連番 FROM test_table
ROW_NUMBERは検索結果に順番をつけることができます。
ROW_NUMBER関数内にある、PARTITION BY でグループ化ができます。
③副問い合わせ
DELETE test_table FROM test_table AS C INNER JOIN ( SELECT aa,bb,cc,dd ,ROW_NUMBER() OVER(PARTITION BY aa,bb,cc,dd ORDER BY aa) AS 連番 FROM test_table ) AS A ON C.aa = A.aa AND C.bb = A.bb AND C.cc = A.cc WHERE 連番 <> 1
副問い合わせは、SELECT文による問い合わせを入れ子にすることです。
③はINNER JOINの中で副問い合わせを行っています。
同じテーブルで、JOINさせているのはROW_NUMBER(連番)をつけるためなのですが、これはまだあやふやなので試す必要があります。
6.28
なんとなくわかってきたような・・・
上司が先輩におっしゃっていたことなのですが、自分も覚えておかなければならないと思ったので書き残しておきます。
自分の行ったこと(書いたプログラムとか)が、今後他のところでどんな影響を受けるのか考えなさい。
自分が作業した後のことまで考えるのは難しいです。
これから少しずつできるようになればいいな・・・。
SqlServerで、ストアドプロシージャを作成 その2
明日記事を書くと言っていたのに、遅れてしまいました。
反省。
前回の続きからです。
IF @header = 1 BEGIN -- BCPコマンド出力設定をする -- 半角スペースある/なしで正常に実行されないので注意する SET @BCP_str = '' SET @BCP_str = 'bcp "' + @SQL_heder_edit +'"' SET @BCP_str = @BCP_str + ' queryout "' + @out_folder + ' Header.csv" ' SET @BCP_str = @BCP_str + '-c -t"," ' SET @BCP_str = @BCP_str + ' -S' + @S_name + ' ' SET @BCP_str = @BCP_str + '-d ' + ' test' + ' ' SET @BCP_str = @BCP_str + '-U ' + @U_id + ' ' SET @BCP_str = @BCP_str + '-P ' + @pass + ' ;' -- CSVファイル実行 -- xp_cmdshell は、OS のコマンドを実行して出力をテキストの行として返す EXECUTE @result = master.dbo.xp_cmdshell @BCP_str IF @result = 1 BEGIN SET @R_Msg = 'ヘッダー作成失敗' RETURN @R_value END END -- BCPの詳細ファイル出力 SET @BCP_str = '' SET @BCP_str = 'bcp "' + @SQL +'"' SET @BCP_str = @BCP_str + ' queryout "' + @out_folder + ' Detail.csv" ' SET @BCP_str = @BCP_str + '-c -t"," ' SET @BCP_str = @BCP_str + ' -S' + @S_name + ' ' SET @BCP_str = @BCP_str + '-d ' + ' test' + ' ' SET @BCP_str = @BCP_str + '-U ' + @U_id + ' ' SET @BCP_str = @BCP_str + '-P ' + @pass + ' ;' EXECUTE @result = master.dbo.xp_cmdshell @BCP_str IF @result = 1 BEGIN SET @R_Msg = '詳細ファイル作成失敗' RETURN @R_value END IF @header = 1 BEGIN -- ヘッダーと詳細のファイル結合 SET @File_copy = '' SET @File_copy = @File_copy + 'copy /B' SET @File_copy = @File_copy + @out_folder + ' Header.csv' SET @File_copy = @File_copy + ' +' SET @File_copy = @File_copy + @out_folder + ' Detail.csv' SET @File_copy = @File_copy + ' ' SET @File_copy = @File_copy + @out_folder + file_name -- CSVファイル結合実行 EXECUTE @result = master.dbo.xp_cmdshell @File_copy END IF @header = 0 BEGIN SET @File_copy = '' SET @File_copy = @File_copy + 'copy /B' SET @File_copy = @File_copy + @out_folder + ' Detail.csv' SET @File_copy = @File_copy + ' ' SET @File_copy = @File_copy + @out_folder + file_name EXECUTE @result = master.dbo.xp_cmdshell @File_copy END IF @header = 1 BEGIN -- ヘッダー消去 SET @File_Del = '' SET @File_Del + ' del /Q' SET @File_Del + @out_folder + ' Header.csv' EXECUTE master.dbo.xp_cmdshell @File_Del END -- 詳細ファイル消去 SET @File_Del = '' SET @File_Del + ' del /Q' SET @File_Del + @out_folder + ' Detail.csv' EXECUTE master.dbo.xp_cmdshell @File_Del END -- 例外エラー END TRY BEGIN CATCH RETURN @R_value -- -1(失敗の値)が代入されている END CATCH SET @R_Msg = CAST(@Cnt AS VARCHAR) + '件を書き込みました。' SET @R_value = 0 --成功の値(戻り値) RETURN @R_value END GO
変数にどんどん代入していって、実行させるための文字列を作成するのが、難しかったです。
仕事を始めて数ヶ月、少しずつ慣れてきました。
まだ沢山学ばねばならないのですが、そろそろキーボードだけでパソコンを動かす方法(ショートカットキーだったかな)も覚えていこうかな。
SqlServerで、ストアドプロシージャを作成 その1
再びストアドを作成したので、2回に渡って復習します。
今回は、カーソル作成までです。
CREATE PROCEDURE SP_ABC ( @file_name VARCHAR(50) ,@table_name VARCHAR(50) ,@out_folder VARCHAR(20) -- 出力先フォルダ(フルパス) ,@S_name VARCHAR(30) ,@U_id VARCHAR(20) ,@pass VARCHAR(20) ,@header CHAR(1) ,@R_Msg VARCHAR(1000) OUTPUT -- 返却メッセージ ) AS DECLARE @hed_str NVARCHAR(3000) -- ↑カーソルからfetchしてきた情報をカンマ区切りで格納 DECLARE @hed_get VARCHAR(50) -- ↑列のヘッダーを格納 DECLARE @SQL NVARCHAR(1000) -- SQL...は、SQL文を格納 DECLARE @SQL_header NVARCHAR(1000) DECLARE @SQL_cursor NVARCHAR(1000) DECLARE @SQL_heder_edit NVARCHAR(1000) DECLARE @BCP_str VARCHAR(3000) DECLARE @File_copy VARCHAR(3000) DECLARE @File_Del VARCHAR(3000) DECLARE @R_value int --戻り値 DECLARE @D_Msg VARCHAR(100) DECLARE @result int DECLARE @Cnt INTEGER BEGIN SET @D_Msg = 'ストアドエラー発生' SET @R_value = -1 BEGIN TRY -- テーブルデータ存在確認 SET @SQL = N' SELECT * FROM ' + @table_name EXECUTE sp_executesql @SQL --SQL実行 SET @Cnt = @@ROWCOUNT IF @Cnt = 0 BEGIN SET @R_Msg = 'データなし' + @table_name RETURN @R_value END -- データ抽出SQL作成 IF @header = 1 BEGIN SET @SQL_header = N' SELECT d.name FROM Sys.tables AS t LEFT OUTER JOIN sys.columns AS c ON t.id = c.id WHRER t.name = ''' + @table_name + '''' + N' ORDER BY c.column_nm ' -- ↑ここがわかりづらい -- テーブルの名前を条件にして、カラムとテーブルを結合 -- Sys.tablesというのはカタログビューと言う。 -- カタログビューは、SqlServerデータベースエンジンによって使用される情報を返す。 EXECUTE sp_executesql @SQL_header SET @SQL_cursor = N' DECLARE aa CURSOR FOR ' + @SQL_header -- ↑先ほど外部結合させるSQL文をカーソルの条件にしている。 EXECUTE sp_executesql @SQL_cursor OPEN aa FETCH NEXT FROM aa INTO @hed_get IF @@FETCH_STATUS = 0 BEGIN SET @hed_str += @hed_get END WHILE @@FETCH_STATUS = 0 BEGIN FETCH NEXT FROM aa INTO @hed_get SET @hed_str += ',' + @hed_get END CLOSE aa DECLARE aa SET @SQL_heder_edit = N'SELECT ' + '''' + @hed_str + '''' END
以上で、カンマ区切りのSELECT文を作成することができました。
これを、csvに出力させるためにbcpユーティリティを使っていきます。
続きはまた明日。
ストアドプロシージャからストアドプロシージャを呼び出す【SqlServer】
昨日は念願の(!)カーソルのあるストアドプロシージャの作成を行いました。
まだ未完成ですが、復習でコードを載せます。
USE testdb GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE PROCEDURE testpro( @aaa VARCHAR(20) ) AS DECLARE @returnval int --戻り値 DECLARE @SQL NVARCHAR(4000) DECLARE @lMsg(4000) --カーソルデータ格納変数 DECLARE @kakunou VARCHAR(1000) BEGIN BEGIN TRY SET @returnval = 1 SET @lMsg = @aaa + 'のデータ移行を開始しました。' EXECUTE testbl '案内','',@aaa,0,@lMsg IF (@aaa IS NULL OR @aaa = '') BEGIN SET @lMsg = '引数が未設定' EXECUTE testbl 'エラー','',@aaa,1,@lMsg RETURN @returnval END --カーソル作成 SET @SQL = 'DECLARE abc CUSOR FOR SELECT tosi From' +'(SELECT name From' + @aaa + ' .table) AS T' EXECUTE sp_executesql @SQL --カーソルオープン OPEN abc --abcから変数@kakunouに1件ずつデータを格納する FETCH NEXT FROM abc INTO @kakunou IF @@FETCH_STATUS <> 0 BEGIN SET @lMsg ='テーブルが存在しません' EXECUTE testbl 'エラー','',@aaa,1,@lMsg RETURN @returnval END While @@FETCH_STATUS = 0 BEGIN EXECUTE abcInsertpro @aaa,@kakunou #処理の後、FETCHで再び1行データを取得する FETCH NEXT From abc INTO @kakunou END CLOSE abc DEALLOCATE abc SET @lMsg = @aaa + 'のデータ移行を完了しました。' EXECUTE testbl '案内','',@aaa,0,@lMsg END TRY --例外エラー BEGIN CATCH SET @lMsg = '[ERROR_NUMBER]' + @SQL EXECUTE testbl 'エラー','',@aaa,1,@lMsg RETURN @returnval END CATCH SET returnval = 0 END GO
@@FETCH_STATUSの設定がおかしいかな?
自分でもわかるように、土日で説明を書くつもりです。
...6月4日追加
データ以降が完了したことを判断する処理は、書かなくても良い(正常に処理されれば、下に流れていくため)
ここから雑記
金曜日に、映画「美しい星」という三島由紀夫原作のSF映画を見ました。
人間は人間自身を自然の一部だと思っていない...だったかな?
個人的にとても面白かったです。