プログラミングの最近のブログ記事

Visual Studio でソリューションにコンソールアプリケーション開発のプロジェクトを追加すると、フレームワークが勝手に Client バージョン?になってしまう。

具体的には、「.NET Framework 4 Client Profile」になってしまう。
しかし、今作ってるプログラムは Client Profile だと機能不足なんよね。

ということで、フレームワークを素の .NET Framework 4 に変更したかったんだけど、あんま Visual Studio も使い込んでいるわけではないので、さて、フレームワークを変更するには・・・と、ネットに頼ったわけよ。

でも、ネット上の情報は、プロジェクトのプロパティ開いて、「アプリケーション」タブの「ターゲット フレームワーク」の一覧から変更したいフレームワークを選択します・・・ってのばっかり。

ふざけんなよ。俺の画面、「ターゲット フレームワーク」のプルダウンなんかねえよ!(バージョン違い?)

20241223_DOTNET1.jpg

結局正解は、

  1. プロジェクトのプロパティを開く(「My Project」ダブルクリックでも可)
  2. 「コンパイル」タブを選択
  3. 画面の一番下の「詳細コンパイル オプション」ボタン押下
  4. 「コンパイラの詳細設定」画面の「対象のフレームワーク」一覧で「.NET Framework 4」選択

これでフレームワークの変更が終了。
一応、メモ。ちょっと悩んだので(^^;

「戻る」ボタン押下で GokeiKeisan っていう JavaScript が実行されてるっぽいんだけど、aspx ファイル見ても、全然 onClick 属性で実行スクリプトの指定をしてないので「なんで?」ってなった。

JavaScript そのものは、aspx ソース内に記述がある。

<script type="text/javascript">
    function GokeiKeisan(objRitsu) {
        var gokeikingaku = 0;
<略>
}

でも、onClick や onChange などの記述はない。

で、VB.NETのソースを見てたら、

Me.btnBack.OnClientClick = "javascript:GokeiKeisan('" & ddlZeiritsu.SelectedValue & "');"

なんて記述が。そうか、ASPではボタンオブジェクトに OnClientClick なんてプロパティがあるんだ。

一覧の手数料や値引額を変更しても合計額が変更されるんだけど、その設定は・・・と思ったら、こちらも VB.NET 内で onChange 属性のセットをしていた。

Dim sScript As String = "GokeiKeisan('" & ddlZeiritsu.SelectedValue & "', sGokei);"        '実行スクリプト
CType(e.Item.FindControl("txtTesuryo"), TextBox).Attributes.Add("onChange", sScript) '手数料が変わったら再計算
CType(e.Item.FindControl("txtNebiki"), TextBox).Attributes.Add("onChange", sScript) '値引額が変わったら再計算

JavaScript だけで属性セットもできるが、VB.NET 側に書いておいたほうが(COBOL から VB6 に流れ、今は VB.NET をやってるけど、JavaScript とかそういうのはわからんよ・・・と堂々と言っちゃうような老害プログラマ、あ、SEか(笑)。そういう人たちにとっても)メンテがやり易いというのはあるのか(^^;;;
VB.NETで、iTextSharp を使って PDF ファイルを生成しているプログラムがあり、その修正をしていたのだが、文字色を変えてくれと言われて色々ググったのだが記事を見つけられなかったのでメモっておく。

iTextSharp の使い方をググっても、本家や一部のエロい人の記事をそのままコピってるような記事が多くて辟易するわ・・・。ソース例をそのまま持ってきてるやつとかな(^^;;; そういうページは検索のときにホントに邪魔だから作らないで・・・と強く思う(笑)

あ、話がずれた。
iTextSharp でフォント色を設定するのは、以下のようなやり方で。
(テンプレートの PDF を読み込んできてアレコレ・・・のところは省きます)

Dim cb As PdfContentByte
' ベースフォントの設定(msmincho.ttc、水平方向文字、フォント埋込をする)
' 日本語フォントはフルパス指定で
Dim bf As BaseFont = BaseFont.CreateFont("c:\windows\fonts\msmincho.ttc,0", BaseFont.IDENTITY_H, True)
cb.BeginText()

cb.SetRGBColorFill(0, 0, 192)    ' 色指定(青 #0000C0)
cb.SetFontAndSize(bf, 13)        ' 文字サイズ 13po

これで、

' 中央よせ(X=100,Y=200 指定したところが中心になる)で文字セット
cb.ShowTextAligned(PdfContentByte.ALIGN_CENTER, "私は慎吾", 100, 200, 0)

とすれば「左下を 0:0」として、文字列の横の中心を 100 の位置とした "私は慎吾" が PDF に設定される。
いやあ、今日は SpreadsheetGear という Excel 互換のスプレッドシート コンポーネントに振り回された一日・・・いや、半日だったけど(笑)・・・だった。

ASP.NET で開発している Web システムがあって、Web画面からアップロードした Excel ファイルをサーバサイドであれこれするんだけど、Excel ファイルによってちゃんと処理できるケースと、「Corrupt OpenXML document.」例外を発生するケースがあるのだ。

<asp:Label ID="lblExcelSel" runat="server" Text="Excelファイル"></asp:Label>&nbsp;
<asp:FileUpload ID="fileExcel" runat="server" />&nbsp;
<asp:Button ID="btnUpFile" runat="server" Text="取込" /> 

こんな感じで、FileUpload コントロールでアップしたデータを、サーバサイドで SpreadsheetGear を使って処理をする。

サーバサイドのプログラムがこんな感じ。

    ''' <summary>
    ''' 取込ボタン処理
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Protected Sub btnUpFile_Click(sender As Object, e As EventArgs) Handles btnUpFile.Click

        ' ファイルがアップロードされていなければ終了
        If (fileExcel.HasFile = False) Then Return

        ' ファイルをメモリーに格納
        Dim data(fileExcel.PostedFile.ContentLength - 1) As Byte
        fileExcel.PostedFile.InputStream.Read(data, 0, fileExcel.PostedFile.ContentLength)

        Dim xlsWorkBookSet As SpreadsheetGear.IWorkbookSet = SpreadsheetGear.Factory.GetWorkbookSet()
        Dim xlsWorkBook As SpreadsheetGear.IWorkbook = Nothing
        Try
            'メモリからワークブックにセット
            xlsWorkBook = xlsWorkBookSet.Workbooks.OpenFromMemory(data)
        Catch ex As Exception
            alert("Excelファイルを読み込めませんでした。(" + ex.Message + ")")
            Return
        End Try

        Dim currentSheet As SpreadsheetGear.IWorksheet = CType(xlsWorkBook.Worksheets(0), SpreadsheetGear.IWorksheet)
<以下略>

この、xlsWorkBook = xlsWorkBookSet.Workbooks.OpenFromMemory(data) しているところで「Corrupt OpenXML document.」例外エラーが発生するのである。

色々調べていたら、他のブックからシートをコピーしたり、他のブックのシートの一部をコピー&ペーストしたファイルがエラーになるようだ。元々ちゃんと読めていたファイルが読めなくなる。

xlsx ファイルは OpenXML 形式のファイルなので、コピー元の情報を書き込んだときに、何か問題が発生するんだろうなあ。日本語ファイル名をシングルクォーテーションで囲まないとか。
まだそこまで調べてないし、調べる時間もなさそうなんで、俺よりエロい人、ぜひご教示くださいませ。

本家サイトにも色々 OpenXML 形式のファイルを扱うときの障害例が載っていたが、そのほとんどが「残念ながら、既知の制限になります。」で締められていて闇を感じた(笑)
Sourcetree で GitHub に 新規プロジェクトの main ブランチを push しようとしたら、GitHub が

git --no-optional-locks -c color.branch=false -c color.diff=false -c color.status=false -c diff.mnemonicprefix=false -c core.quotepath=false -c credential.helper=sourcetree push -v --tags origin refs/heads/main:refs/heads/main 
Pushing to ssh://github.com/XXXXXXX/sXXXXXXX.git
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.

というエラーを出して失敗する。
よくわからないが、どうも「Permission denied (publickey)」というメッセージから、公開鍵(PublicKey)の問題のようだ。

いや、もちろん思い当たる(^^;;;
ええと、SSH 接続用の秘密鍵も公開鍵も作ってましぇん(^^;;;

というわけで、下記に対応手順。
やり方は GitHub Docs に載っている手順通り。
この俺のブログ(このページ)も含めて(笑)、ネット上の情報は古くなっているものが多いので、GitHub Docs のような正規のドキュメントを参照した方がいいよ。

・新しい SSHキー(秘密鍵、公開鍵)の作成
※ GitHub に登録しているメールアドレスで作成
※ ディフォルトの名前を変更して作成(ケツに GitHub と付ける)

% ssh-keygen -t ed25519 -C "hogehoge@exsample.com"
Generating public/private ed25519 key pair.
Enter file in which to save the key (/Users/hogehoge/.ssh/id_ed25519): /Users/hogehoge/.ssh/id_ed25519_GitHub
Enter passphrase (empty for no passphrase): <パスフレーズ>
Enter same passphrase again: <パスフレーズ>
Your identification has been saved in /Users/hogehoge/.ssh/id_ed25519_GitHub
Your public key has been saved in /Users/hogehoge/.ssh/id_ed25519_GitHub.pub
The key fingerprint is:
SHA256:oKy<略>h4 hogehoge@exsample.com
The key's randomart image is:
+--[ED25519 256]--+
|           .=..  |
|           o.+   |
|      .    .=E   |
|   . . . ..++o.  |
|    + o S ..+.+ o|
|   o . + .   = =+|
|  o       .   B.*|
|oo.        . + X+|
|*=.         . =o=|
+----[SHA256]-----+

・ssh-agent の起動
% eval "$(ssh-agent -s)"
Agent pid 6763

・~/.ssh/config ファイルの作成
% open ~/.ssh/config
The file /Users/hogehoge/.ssh/config does not exist.

存在していないので空ファイルを作成
% touch ~/.ssh/config

・config ファイルの編集
% vi ~/.ssh/config
% cat ~/.ssh/config
Host github.com
  AddKeysToAgent yes
  UseKeychain yes
  IdentityFile ~/.ssh/id_ed25519_GitHub

※ UseKeychain yes 行を書かなければ、キーにパスフレーズを追加しないようにできるらしい

・作成した SSH 秘密鍵を ssh-agent に追加する
% ssh-add --apple-use-keychain ~/.ssh/id_ed25519_GitHub
Enter passphrase for /Users/hogehoge/.ssh/id_ed25519_GitHub: <パスフレーズ>
Identity added: /Users/hogehoge/.ssh/id_ed25519_GitHub (hogehoge@exsample.com)

・SSH 公開鍵をクリップボードにコピー
% pbcopy < ~/.ssh/id_ed25519_GitHub.pub

※ .pub がついている公開鍵をコピーしよう。俺は .pub のついていない秘密鍵の方をコピーして GitHub から「Key is invalid. You must supply a key in OpenSSH public key format」と叱られた

・New SSH key の登録
Web で GitHub にログインし、設定画面を開く→[アクセス] セクションの[SSH キーと GPG キー]を開き、New SSH Key の登録を行う

以上の処置で、無事 push ができるようになった。
よかった、よかった(笑)
VB.NET で画面の表にバインドしているデータテーブルの中身を、編集前、編集後の値で比較してほげほげしたいという処理がある。

データテーブルのレコード自体は、編集前のものであれば列名の後ろに DataRowVersion.Original というバージョン情報を引数で設定してやればいい。
編集前は dr("人数", DataRowVersion.Original) 、編集後の値は dr("人数") という具合

そこで、例えば職種をキーとしたハッシュテーブル(連想配列)に編集前と編集後の人数をセットしていって、あとで同じキー(同じ職種)の人数の変異を見たいと思って、

For Each dr As DataRow In DataTable1.Rows
    HTOld(dr("職種", DataRowVersion.Original).ToString) = dr("人数", DataRowVersion.Original).ToString
    HTNew(dr("職種").ToString) = dr("人数").ToString
Next

なんてやると、編集前の値のない行(つまり、追加された行)データが出てくると、

System.Data.VersionNotFoundException: 'アクセスする Original データがありません。'

という例外が発生する。

Not IsDBNull(dr("職種", DataRowVersion.Original)) とかしたら回避できるかなとも思ったけど、データがそもそも無いので Null でもない。

Try で例外引っ掛けて、それを「オリジナル行のない追加されたデータである」と判断してもいいかなとも思ったが、結局、RowState をチェックすることで回避した。

If dr.RowState <> DataRowState.Added Then
    HTOld(dr("職種", DataRowVersion.Original).ToString) = dr("人数", DataRowVersion.Original).ToString
End If

If dr.RowState <> DataRowState.Deleted Then
    HTOld(dr("職種") = dr("人数").ToString
End If

みたいな感じ。

他にきれいなやり方があるのなら教えてほしい>VB.NET マスターの皆さん

Perl 使いの俺としては、こういう処理で引っかかるの、本当に面倒くさくていや(笑)
VB.NET で DataGridView で作成した表の列固定(Excelで「ウィンドウ枠の固定」って言うやつやね)を行いたい。
それも、動的に。

ある検索条件で取得したデータを展開したときは 2列目で、他の検索条件のときは 5列目を・・・みたいな感じ。

IF hogehoge THEN
    dataGrid1.Columns(1).Frozen = True
ELSE
    dataGrid1.Columns(4).Frozen = True
END IF

こんなんでいいかなと。

そしたら、一旦 5列目で列固定したあとに 2列目の列固定に戻らないのよ。
.Columns(1).Frozen = True を実行しても、列固定は 5列目で行われているまま。

もしかして、現在設定中の列固定位置を一旦クリアしてからセットし直せばいいのかな?と思って、

IF hogehoge THEN
    dataGrid1.Columns(4).Frozen = False
    dataGrid1.Columns(1).Frozen = True
ELSE
    dataGrid1.Columns(1).Frozen = False
    dataGrid1.Columns(4).Frozen = True
END IF

とかやってみたけど状況変わらず。
ただ、.Columns(4).Frozen = False ってやると、5列目じゃなく 4列目が固定されているな。列固定が左にひとつ動いた(笑)

どうも、.Columns(4).Frozen = True とした時点で、5列目まで全列で列固定が True になってるんだな(^^;
だから、.Columns(1).Frozen = True としても、もともと 1~5列目まで全て True になっている状態なので何も変わらない(^^;

というわけで、Frozen のセットをする前に、

FOR i AS Integer 0 TO dataGrid1.Columns.Count - 1 
    dataGrid1.Columns(i).Frozen = False
NEXT

してから処理するようにしたら、無事、2列目の固定が有効になった。

しかし、多分、なんか一発で Frozen をクリアする方法はあるんだろうな(笑)。Frozen そのものを有効/無効にするプロパティがあるみたいなんで、あれで一旦無効にすれば Frozen の設定は一旦全クリアされるかもしれんね。もう動いてるんで試してみないけど(笑)

ところで、ネット上を調べてみたけど、こういう動的に固定列を変更して云々みたいな説明しているページ、ひとつもなかったな。
皆、Microsoft や有名ブロガーのページのコピーばかりで「列固定する方法」しか載ってない。役に立たんわぁ~(^^;
随分前に作った Linux(CentOS)上で動くプログラム。
LZH ファイルを解凍し、そのファイルをほげほげするのだが、さすがにもう Windows 上で LZH ファイルを作るのもきつくなってきた・・・ということで ZIP ファイル対応を依頼されたのだが(例えば、7-Zip なんかでも LZH 形式には対応してないからな(^^;)・・・ハマった(^^;

yum で入れた unzip は -O オプション(アーカイブ内のファイル名のエンコードが指定できる)が使える(以前のバージョンではパッチを当てないと駄目だった)ので、例えば unzip -Ocp932 -l exsample.zip で、exsample.zip の中の「かわいい中年男性一覧.csv」みたいなファイル名は取ってこれるんだけど、これをディスク上に解凍するとファイル名が化けまくる・・・

ちなみに、プログラムは EUC-JP で書かれている。なにせ、もう、18年前に初版公開したプログラムだからな(笑)。

これ、lha コマンドは EUC-JP でファイル名を出力するパッチが当たっていたので問題なかったんだけど、unzip は「サーバの locale のエンコードでファイル名が作られる」ため、実行サーバの locale である UTF-8 のファイル名となる。

他のプログラムにも影響あるから、なんとか EUC-JP でファイル名を設定してほしいなあ。

しかし、unzip にそのようなオプションはない。結局、unzip を実行する前に、locale を EUC-JP にする形でなんとかなった。

(例)
export LC_CTYPE=ja_JP.eucJP; /usr/bin/unzip -OCP932 -d /tmp exsample.zip

このプログラムは実行後シェルを閉じるので、LC_CTYPE の設定を投げっぱなしだが、同一シェル内で他のコマンドなど実行するのなら、

export LC_CTYPE=ja_JP.UTF-8

で locale を元の UTF-8 に戻すこと。

Tedious ドライバーを使って SQL Server に接続できない・・・」というエントリーに書いたように、Tedious ドライバーを使って JavaScript(node.js)からの SQL Server 2019 へのアクセスだけがうまくいかない。

C# で試しにコンソールプログラム作ってアクセスしてみたけど、やっぱりうまくいくなあ。

Program.cs はこんな感じ。

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

dbaccess();

        static void dbaccess()
        {
            string dataSource, initCatalog, userId, passWord, connectionString;
            dataSource = "DBSERVER\\MSSQL2019";
            initCatalog = "InazumaDB";
            userId = "sa";
            passWord = "hogepass";
            connectionString = @"Data Source=" + dataSource + ";Initial Catalog=" + initCatalog + ";User ID=" + userId + ";Password=" + passWord;
            string query_s = "SELECT TOMO_ID, TOMO_NAME, TOMO_MEMO FROM InazumaDB.dbo.M_TOMODACHI";

            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                //接続
                conn.Open();

                //SQL文を作成
                SqlCommand command_s = new SqlCommand(query_s, conn);

                using (SqlDataReader reader = command_s.ExecuteReader())
                {
                    //繰り返し読み込み
                    while (reader.Read())
                    {
                        //1~3列目の値を表示
                        Console.WriteLine(String.Format("{0}, {1}, {2}", reader[0], reader[1], reader[2]));
                    }
                }
                conn.Close();
            }
        }

これを実行すれば、コンソールに、

      1, アンモニア治郎, おごってくれるから友達
      2, クロム陽子, かわいいから友達
     14, ばいじん太郎, 事業に失敗したからそろそろ切ろう

こういう結果が表示される。

やっぱり、Tedious ドライバーが古くて SQL Server 2019 に対応していないってオチなんかね?

しばらく別件で忙しいので、調べている時間がないが・・・

Blazor で作成するのはだいたい企業内の Web システムだと思う。オープンなサイトをわざわざこんな糞重いフレームワークで組む人はいないだろう(よっぽどの Microsoft 好きか C# 以外の言語がまったくできない人を除いて).

今、Blazor で構築を予定しているサイトもやはり企業向けの Web サイトでログイン認証が必要である。
最初、自前でログイン画面を作って組み込んだ人のサイトなど見て勉強していたのだが、Blazor ってちゃんと「認証付きWeb画面」のテンプレートが用意されてるね。

新規プロジェクとで「Blazor WebAssembly アプリ」を選択。

20230804_blazer21.jpg

とりあえずテストなので、プロジェクト名などはそのままで「次へ」。

20230804_blazer22.jpg

そして、「認証の種類」で「なし」から「個別のアカウント」に変更して「作成」。
ちなみに、下に表示されていたチェック項目の「HTTPS用の構成」は「個別のアカウント」を選択すると消える。認証するときには SSL が前提なのでは選択不可(常に選択)になるということだろうなあ。

20230804_blazer23.jpg

これで作成されたプロジェクトを実行すると、画面の右上に「Login」というリンクが作成されている。

この Login をクリックしてみると、「フォームがモジュールにありません 読み込まれたモジュールに現在のスタック フレームが見つかりませんでした。この場所のソースは表示できません。」と VisualStudio 上に表示。そのまま処理を続けると、ブラウザの「There was an error trying to log you in: 'Network Error'」と表示された。

ま、なんの処理も書いてないからな(笑)

実際の認証処理作成の話はまた別のエントリーで。

このアーカイブについて

このページには、過去に書かれたブログ記事のうちプログラミングカテゴリに属しているものが含まれています。

前のカテゴリはパソコンです。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

月別 アーカイブ

電気ウナギ的○○ mobile ver.

携帯版「電気ウナギ的○○」はこちら