プログラミングと日々思ったことなど

ブログ名通りです。仕事でプログラミングをはじめました。

Javaを個人的にはじめて、反省に至るまで【Java】

前回の記事から、随分経ってしまいました。

6月ごろから友人と二人で、少しずつ開発をしています。
その経過を書いていきます。

開発環境

macOS Sierra
Java 8
Eclipse(Neon)


参考にしたぺージ

初心者でもほぼ無料でJavaを勉強できるコンテンツ10選 - paiza開発日誌

Angular 2 画面遷移

mobile:初心者のためのSpring Framework入門


1.eclipseでダウンロードから、データベース接続に至るまで。

まず、eclipseで動的プロジェクトを作成し、サイトを参考にしながらデータベース接続画面を作成してみました。
そして実行してみますが・・・
f:id:boa0203:20170916180808p:plain

できない。
リソースが無いと言われてしまったので、何かが足りないのだと思い試行錯誤しました。
ですが原因がわからなかったので、経験者に質問。
助言と参考画面をもらいました。

助言
・contextかserverファイルの書き方が間違っているのでは。
JSPTOMCAT をビルドすると、変なファイルが作られるときもあるので、キャッシュのクリアをした方が良いかもしれない。
Tomcatapache連携する。
JSONでパラメータを与えて非同期にする。

!context.xml
アプリケーションの配置場所や呼び出し方などの情報を設定するファイル。

!server.xml
Tomcatサーバの動作を定義する設定するファイル。

参考画像を元に、自分のDB接続設定のコードを確認したところ書き方の違いを発見。
書き直したところ、接続ができました。

2.画面にデータベースから取得したデータを表示するまで。

接続はできたので、今度は取得したデータの表示に取り掛かりました。
1で取ってこれた接続設定と、servletを使用してデータを表示したかったのですが、データの表示がうまくいきませんでした。
このservletの書き方が理解できず、時間を費やしてしまい焦りだし、結局サンプルのjspに直書きするものでなんとか表示させました。

f:id:boa0203:20170916235837p:plain


Servlet
サーバー上で動く部品のようなもの。Java言語で記述される。
MVCではControlにあたる。

JSP
HTML上に直接記述できるJava言語。
MVCではViewにあたる。

servletjspの違い
servletは常にコンパイルが必要だが、jspサーブレットエンジンがjspファイルを自動的に変換してくれる。
なので、jspservletに変換される。

MVCについて
Model、View、Control と役割分担をしてプログラムを作成する方法。
役割の内容
Control ・・・ DB関連
View ・・・ 画面表示
Model ・・・ 処理結果をViewに返す(ModelとViewの仲介、制御)

JavaでのModelはJavaBeansになる。JavaBeans自体は、直接クライアントから呼び出されることはない。(仲介、制御なので)

3.表示したデータから1つのデータを選択して、それを別のページに持って行くまで。
次に1つのデータを選択して、次のページに表示する処理を作ろうと考えました。
が、何をすれば良いのかわからず、経験者にお聞きしました。

<%@page contentType="text/html"%> 

<%@page import="java.sql.*"%>

<%!

// サーブレットのinitメソッドに相当

public void jspInit() {

    try {

        // JDBCドライバをロード

        Class.forName("com.mysql.jdbc.Driver");

    } catch (Exception e) {

        e.printStackTrace();

    }

}

%>

<html> 

<body> 


<%=session.getAttribute("mysql")%> 

<%= request.getParameter("eid")%>

</body> 

</html> 


そしてメソッドを使用して、次画面に持って来ることができました。

・・・ここから、jspservletやプロジェクトの中身などについて調べて行ったり来たりしますが・・・理解が追いつかなくなりました。

4.フレームワークを使用する

理解が追いつかなくなってきたので、経験者が教えてくれたフレームワークを使用しようと試みます。

使ってみたのは、Angular 2です。

f:id:boa0203:20170917012222p:plain

参考ページそのままの画面を表示できました。
ですが、このAngular 2の使用はやめることにしました。
コンポーネント指向、開発言語(TypeScript)の理解が必要だからです。
JavaScriptコードもままならないのに、無謀でした。

このAngular 2を少しだけ動かし、Java自体をもう一度やり直そうと反省しました。

5.現在

反省して今度はSpringフレームワークを調べつつ、画面を作っています。
・・・この記事は戒めです・・・。

別クラスから、メソッドを操作する【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ユーティリティを使っていきます。


続きはまた明日。