質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

解決済

2回答

1821閲覧

【VB.NET】Accessファイルを読み込んで、.datファイルに出力する

SB_AK

総合スコア1

ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

0グッド

0クリップ

投稿2020/04/23 13:48

編集2020/04/24 00:54

前提・実現したいこと

Accessファイルを読み込み、.datファイルに読み込んだデータを出力するプログラムを開発中です。
※AccessファイルはユーザーDSNで接続済み
※コンソールプログラムで開発中

【Accessファイルの構造】
社員ID = 短いテキスト
社員氏名 = 短いテキスト
部門No = 短いテキスト
入社日 = 日付/時刻型
退職日 = 日付/時刻型
出身 = 短いテキスト
部門名 = 短いテキスト
※NULL可のフィールドはありません。

【Accessファイルの中身】※.accdbファイルです。
■社員テーブル
社員ID 社員氏名 部門No 入社日 退職日     出身
00001 田中太郎 001 2000/04/01 2001/04/01  東京
00002 山田太郎 002 2001/04/01 2002/05/01 埼玉
00003 鈴木太郎 003 2002/04/01 2003/06/01 千葉

■部門テーブル
部門No 部門名
001 営業部
002 総務部
003 開発部

【datファイルへの出力イメージ】※ヘッダ・フィールドとの間はタブ区切りで出力
社員ID 社員氏名 部門No 部門名 入社日 退職日 勤続年数 出身
00001 田中太郎 001 営業部 2000年04月 2000年04月01日  1年0ヶ月 東京
00002 山田太郎 002 総務部 2001年04月 2002年05月01日 1年1ヶ月 埼玉
00003 鈴木太郎 003 開発部 2002年04月 2003年06月01日 1年2ヶ月 千葉

ここでは全員退職者という設定でお願いします。

困っていること/分からないこと

① 上記に記載の【datファイルへの出力イメージ】のようなヘッダ・フィールドの順番で出力するための正しい書き方がわからない。
どこに、どのような順番でコードを書けば良いかが分かりません。現在のコードだと任意の位置に出力してくれません。

② 上記に記載の【datファイルへの出力イメージ】のように"勤続年数"を算出する方法が分からない。

③ 上記に記載の【datファイルへの出力イメージ】の〇年〇月や〇年〇月〇日、〇年〇ヶ月というように出力するための書き方が分からない。同じくどこに、どのような方法でコードを書けば良いかが分かりません。

作成中のソースコード

Imports Systen.DataI.Odbc Imports System.Windows.Forms Imports System.IO Module Module1 Sub Main() Dim con As New System.Data.Odbc.OdbcConnection Dim command As New System.Data.Odbc.OdbcCommand Dim Adapter As New System.Data.Odbc.OdbcDataAdapter(command) Dim Syaintable As New DataTable Dim Bumontable As New DataTable Try '接続文字列 con.ConnectionString = "DSN=sampleDB" 'DBオープン con.Open() '列作成(社員テーブル) SyainTable.Columns.Add("社員ID", Type.GetType("System.String")) SyainTable.Columns.Add("社員氏名", Type.GetType("System.String")) SyainTable.Columns.Add("部門No", Type.GetType("System.String")) SyainTable.Columns.Add("入社日", Type.GetType("System.DateTime")) SyainTable.Columns.Add("退職日", Type.GetType("System.DateTime")) SyainTable.Columns.Add("出身", Type.GetType("System.String")) '列作成(部門テーブル) Bumontable.Colmuns.Add("部門No", Type.GetType("System.String")) Bumontable.Colmuns.Add("部門名", Type.GetType("System.String")) 'DataSetに格納 Dim ds As New DataSet ds.Tables.Add(SyainTable) ds.Tables.Add(BumonTable) 'コマンド command = con.CreateCommand 'SQL command.CommandText = "出力イメージになるようなSQLをここに書く" Adapter.SelectCommand = command      'DataTableに格納する Adapter.Fill(SyainTable) Adapter.Fill(Bumontable)      'ファイルパス Dim FilePath As String FilePath = "output.dat"      '出力するためのファイルを開く処理 Dim sw As New System.IO.StreamWriter(FilePath, False, System.Text.Encoding.GetEncoding("shift_jis"))      '変数用意 Dim colCount As Integer = SyainTable.Columns.Count Dim lastColIndex As Integer = colCount -1 'ヘッダを書き込む Dim i As Integer For i = 0 To colCount -1 'ヘッダの取得 Dim field As String = SyainTable.Columns(i).Caption 'フィールドを書き込む sw.Write(field) 'タブ区切りで書き込む If lastColIndex > i Then sw.Write(Tab) End If Next '改行する sw.WriteLine() 'レコードを書き込む For Each row In SyainTable.Rows         Dim strTSV As String strTSV = "" strTSV = strTSV & row("社員ID").ToString() & Tab strTSV = strTSV & row("社員氏名").ToString() & Tab strTSV = strTSV & row("部門No").ToString() & Tab strTSV = strTSV & row("部門名").ToString() & Tab strTSV = strTSV & row("入社日").ToString() & Tab strTSV = strTSV & row("退職日").ToString() & Tab strTSV = strTSV & row("出身").ToString()        '改行する sw.WriteLine(strTSV) Next 'sw.Close() Catch ex As Exception MessageBox.Show(ex.Message, "エラー") End Try SyainTable.Dispose() Adapter.Dispose() command.Dispose() con.Close() con.Dispose() MessageBox.Show("処理が終了しました", "通知") End Sub End Module

補足情報(FW/ツールのバージョンなど)

OS:Windows10
開発ツール:Visual Studio2019
フレームワーク:.NET Framework4.8

VBを学び始めてまだ日が浅く、意味のないロジックや無駄なコードがあるかもしれませんが、併せて教えていただければ幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/04/23 23:25

Access のテーブルの構造、特に各フィールドの型、はどうなっているのでしょう? 全員退職者何ですか? 在職者はどうするのですか? .accdb か .mdb どちらですか?
SB_AK

2020/04/24 00:39 編集

社員ID = 短いテキスト 社員氏名 = 短いテキスト 部門No = 短いテキスト 入社日 = 日付/時刻型 退職日 = 日付/時刻型 出身 = 短いテキスト 部門名 = 短いテキスト ここでは全員退職者での設定でお願いします。 .accdbファイルです。
退会済みユーザー

退会済みユーザー

2020/04/24 00:45

上記を質問欄を編集して追記してください。コメント欄での情報提供は好ましくないです。初期画面ではコメント欄は開かないので読まない人がいますから。
退会済みユーザー

退会済みユーザー

2020/04/24 00:50

聞き忘れました。NULL 可のフィールドはありますか? それはどれですか? これも質問欄を編集して追記してください。
SB_AK

2020/04/24 00:54

それぞれ質問欄に反映させました。
guest

回答2

0

ベストアンサー

Access の「社員テーブル」と「部門テーブル」のデータを別々の DataTable に取得するところまではできていると理解してレスします。(ホントはそれは無駄なような気がしますが、その話はちょっと置いときます)

① 上記に記載の【datファイルへの出力イメージ】のようなヘッダ・フィールドの順番で出力するための正しい書き方がわからない。

どこに、どのような順番でコードを書けば良いかが分かりません。現在のコードだと任意の位置に出力してくれません。

すでに「社員テーブル」と「部門テーブル」の別々の DataTable が取得できているのでそれらを利用するとして・・・

まず、【datファイルへの出力イメージ】のもとになるデータを List(Of T) オブジェクト(DataTable ではなく)として取得することにします。その T クラスの定義を追加してください。

DataTableExtensions.AsEnumerable メソッドを使って、それぞれの DataTable から EnumerableRowCollection(Of TRow) オブジェクトを取得し、それらを Linq to Object を使って結合して List(Of T) 型オブジェクトを生成します。

以下のような感じです(あくまで感じ。コードは C# です)。上でいう T クラスが下の画像の Result クラスに該当します(下の例では内部結合の結果 List(Of Result) オブジェクトが取得できています)。質問者さんのケースでは、上で言う T クラスのプロパティは全部 String 型で良いと思います。

イメージ説明

② 上記に記載の【datファイルへの出力イメージ】のように"勤続年数"を算出する方法が分からない。

「入社日」と「退職日」は DataTable では DateTime 型になっていると思います(確認してください)。であれば、上の画像の Select new Result { ... } の ... で "勤続年数" に該当するプロパティに値を代入する際、「入社日」と「退職日」の値を引き算して(結果は TimeSpan 型になるはず)〇年〇ヶ月という文字列に書式設定すれば望む結果が得られるはずです。

③ 上記に記載の【datファイルへの出力イメージ】の〇年〇月や〇年〇月〇日、〇年〇ヶ月というように出力するための書き方が分からない。同じくどこに、どのような方法でコードを書けば良いかが分かりません。

DateTime 型、TimeSpan 型から書式設定をして文字列に変換してください。詳しくは以下の記事を見てください。

カスタム日時形式文字列
https://docs.microsoft.com/ja-jp/dotnet/standard/base-types/custom-date-and-time-format-strings

カスタム TimeSpan 書式指定文字列
https://docs.microsoft.com/ja-jp/dotnet/standard/base-types/custom-timespan-format-strings

以上で【datファイルへの出力イメージ】のもとになる List(Of T) オブジェクトが生成できるはずです。それから質問者さんの言う .dat ファイルは容易に作れるはずです。

投稿2020/04/24 02:07

編集2020/04/24 09:19
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

SB_AK

2020/04/24 06:32 編集

回答ありがとうございます。 日時を指定の書式にするところでToStringメソッドで以下のようにしてみたところ、エラーが発生しました。 strTSV = strTSV & row("入社日").ToString("yy年mm月") & Tab エラーメッセージは、「String型"yy年mm月"から型'integer'への変換は無効です」と出ましたが、書き方が悪いのでしょうか?それとも別の個所に問題があるのでしょうか?
退会済みユーザー

退会済みユーザー

2020/04/24 06:37

私が回答したことと質問者さんがやってることが違いませんか? 回答を無視して別のところに走って行ってしまわれたようですが、それではフォローしきれません。そもそもそのコードが一体何なのかも不明ですし。
退会済みユーザー

退会済みユーザー

2020/04/24 06:46

まず、回答に対してフィードバックしてください。分かった・分からなかった、役に立った・立たなかった、分からなかった/役に立たなかったならどこがダメなのか、それを書いてください。話はそれらにさせてください。
SB_AK

2020/04/24 07:05 編集

そうですね。失礼いたしました。 率直に申し上げると、書いていただいたご説明が分かりにくいです。 また作成されたコードも画像でアップして頂いているようですが、言語がC#です。 私はVB以外は触ったことがないので、C#で書かれると解読するのに時間を要するのと、混乱します。 C#を勉強したいわけではありません。 回答者様が感じておられるより、私のスキルはまだまだ低いです。(投稿にも記載していますが) 提案して頂いた内容で十分解決になるのでしょうが、私にとっては高度なテクニックに感じました。 綺麗なロジックやコードを書きたいのではなく、べた書きになっても良いので、「こうしたいならこう」、「この場合はここに、XXXXと書けば良い」など、もっとシンプルでもかまいません。 そして記事のリンクを貼っていただいたのは嬉しいのですが、投稿する前からすでに目を通しています。ですが、MSのサイトは事務的で理解しがたいので、ここに質問しています。 より分かりやすいアドバイスを頂きたく、ここに質問しています。
退会済みユーザー

退会済みユーザー

2020/04/24 07:45 編集

いろいろなことをまとめて聞いてますが、それに対して全体的に自分としては解決に一番最短距離だと思う方法を書いてます。 > もっとシンプルでもかまいません。 そうでないと話が通じないなら、質問もシンプルにしないとダメでしょう。DateTime 型を文字列にする際の書式設定の話が聞きたいのなら、それだけに限った質問をするとか。 > 投稿する前からすでに目を通しています。 そうであれば、それは最初の質問に自分が知っていることとして書いてください。情報を提供するとそんなことは知っているという人が結構いますが、そういうのは結構カチンと来ますよ。
退会済みユーザー

退会済みユーザー

2020/04/25 03:05

質問者さんが無言になってしまいましたが、上の回答の案での実現はギブアップですか? それならそう書いてください。 せっかく作った 2 つの DataTable は放棄してゼロから考えるのでよければ、たぶん質問者さんにとって一番高い壁であろう Linq to Object を使わないで、ごく基本的なコードで解決する方法もあります。 もう止めたということならそれでも結構ですので、その旨書いてこのスレッドはクローズしてください。 とにかく無言は NG です。
SB_AK

2020/04/26 14:50

返信遅くなり失礼しました。 少し別のロジックで再構築してみます。 ただせっかくここまでアドバイスを頂いたので、今回はSuferさんにBAとします。 そしてもう少し自分が分かっていないことを分解して、改めて別の質問でアドバイスを頂こうと思います。 回答ありがとうございました。
guest

0

① 上記に記載の【datファイルへの出力イメージ】のようなヘッダ・フィールドの順番で出力するための正しい書き方がわからない。

どこに、どのような順番でコードを書けば良いかが分かりません。現在のコードだと任意の位置に出力してくれません。

datてなんじゃ…と思ったらタブ区切りテキストね。

そういうのはCsvHelperみたいなライブラリ使えば良いと思う。

② 上記に記載の【datファイルへの出力イメージ】のように"勤続年数"を算出する方法が分からない。
③ 上記に記載の【datファイルへの出力イメージ】の〇年〇月や〇年〇月〇日、〇年〇ヶ月というように出力するための書き方が分からない。同じくどこに、どのような方法でコードを書けば良いかが分かりません。

1から10まで説明するようなモノでもないので、方針のみで。

方法は何種類でもあると思うけど、それを導出するためのプロパティを持ったクラスを用意しておき、取得したデータの中身を全部マップしてやれば良いと思われる。

いまの構造を極力そのままやりたいなら、SQLでその計算をしたり文字列のフォーマットまでしておく、という手もあるけど。

投稿2020/04/23 15:02

gentaro

総合スコア8949

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

SB_AK

2020/04/24 01:22

回答ありがとうございます。 すいません、まだ自分のスキルがそこまで到達していないもので、あまり高度なことはまだできる自信がありません。下手にやろうとすると逆に混乱してしまう恐れがあるので。 少々べた書きになっても問題ありませんので、もう少し詳細なヒントを教えて頂ければ助かります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問