วันเสาร์ที่ 28 กันยายน พ.ศ. 2562

การอ่านเขียน ค่า Registry ด้วย Autolisp

ในการอ่านค่า Registry ด้วย Autolisp ต้องใช้ตามนี้ ใน Help ของ Autodesk ผิด

 (vl-registry-read "HKEY_CURRENT_USER\\Software\\<ชื่อกับ sub ที่ต้องการ>" "<key>")

กรณี Write
(vl-registry-write "HKEY_CURRENT_USER\\Software\\<ชื่อกับ sub ที่ต้องการ>" "<key>" "value")

วันพุธที่ 18 กันยายน พ.ศ. 2562

วิธีอ่านชื่อ Family and Type ขอ Element


  ในกรณีที่เราต้องการ ดู Family name ,Type name ของ Family จาก Element Id          


               Element e = doc.GetElement(elementId);

                Element et = doc.GetElement(e.GetTypeId()); // ไปอ่าน type 
                ElementType etype = et as ElementType;
                if (etype == null)
                    return;

              // ชื่อ type เช่น 100x100 mm.
             string typeN= etype.Name;

                FamilyInstance elFamInst = e as FamilyInstance;
                Family elFam = elFamInst.Symbol.Family;
             // ชื่อ Family เช่น Rectangular Column
            string fname =elFam.Name;
               

ค้น ทั้ง Element และ Type ใช้ c# Linq ใน Revit


Revit เก็บ Object ใน รูปแบบ element โดยมี Key เป็น ElementId การค้นมี tool ชื่อ FilteredElementCollector  
การใช้งาน ให้ใช้คู่กับ Linq 
OfClass หมายถึง type ที่ต้องการหา เช่น typeof( Family) หรือ typeof(DimensionType) เป็นต้น และ กำหนด ชื่อ จาก targetname

public static Element FindElementByName(
    Document doc,
    Type targetType,
    string targetName)
        {
            return new FilteredElementCollector(doc)
              .OfClass(targetType)
              .FirstOrDefault<Element>(
                e => e.Name.Equals(targetName));
        }

Load Family จาก File ใน Revit

การ Load Family จากไฟล์ .จะมีชื่อกับ Type ตาม file

string FamilyName = "ชื่อ Family";
string FamilyPath = "c:/temp/ชื่อ Family.rfa";


  Family family = FindElementByName( doc, typeof(Family), FamilyName) as Family;

            if (family != null) return; //already exist

            if (!File.Exists(FamilyPath))
            {
               MessageBox.Show(string.Format(
                  "Please ensure that the sample table "
                  + "family file '{0}' exists in '{1}'.",
                  FamilyName, path));

                return ;
            }

            // Load family from file:

            using (Transaction tx = new Transaction(doc))
            {
                tx.Start("Load Family");
                doc.LoadFamily(FamilyPath, out family);
                
                tx.Commit();
            }

วันอังคารที่ 17 กันยายน พ.ศ. 2562

Json ใน SQL Server 2017 และสร้าง Class ใน C#

Json ใช้ในระบบของ Javascript และ การติดต่อ ระหว่าง Cloud ระหว่างหลายภาษา เช่น python, java, dotnet. SQL Server 2017 มี Feature นี้ ด้วย

ก่อนอื่นต้อง Upgrade database ก่อน
ALTER DATABASE [TestDB] SET COMPATIBILITY_LEVEL = 130

ทดลอง Data ที่เป็น JSON

DECLARE @JSONData AS NVARCHAR(4000)
SET @JSONData = N'{
    "EmployeeInfo":{
        "FirstName":"Somchai",
        "LastName":"Saema",
        "Code":"CODED",
        "Addresses":[
            { "Address":"1234", "City":"Bangkok", "State":THAILAND"},
            { "Address":"5678", "City":"Nonthaburi", "State":"THAILAND"}
        ]
    }
}'

ตัวเช็ก ว่าเป็น Json หรือไม่
select isjson(@jsondata)
อ่านค่า
select json_value(@jsondata,'$.EmployeeInfo.Addresses[1].Address')

ดูว่าใช่หรือไม่
select isjson(@jsondata)
ดูค่า
select json_value(@jsondata,'$.EmployeeInfo.Addresses[1].Address')
select JSON_query(@jsondata,'$.EmployeeInfo.Addresses')
แก้
SET @JSONData = JSON_MODIFY(@JSONData,'$.EmployeeInfo.FirstName', 'Name'')
select json_value(@jsondata,'$.EmployeeInfo.FirstName')
เพิ่ม
SET @JSONData = JSON_MODIFY(@JSONData,'$.EmployeeInfo.MiddleName', 'NNK')
select JSON_value(@jsondata,'$.EmployeeInfo.MiddleName')

select * from openjson(@jsondata)
Select JSON_query(@jsondata,'$.EmployeeInfo.Addresses')
แก้ ค่า
SET @JSONData = JSON_MODIFY(@JSONData,'$.EmployeeInfo.FirstName', 'Rakesh')
select json_value(@jsondata,'$.EmployeeInfo.FirstName')
เพิ่ม field
SET @JSONData = JSON_MODIFY(@JSONData,'$.EmployeeInfo.MiddleName', 'MAI')
select JSON_value(@jsondata,'$.EmployeeInfo.MiddleName')

select * from openjson(@jsondata)

การ Update จะมา เป็น JSON ต้อง แตกออก โดยใช้ OPENJSON
DECLARE @v AS NVARCHAR(4000)
set @v='{"UserID":7,"UserName":"Somsak","RegDate":"2017-01-23T00:00:00"}'

ถ้า select * from OPENJSON(@v)
จะได้
 key .  value . type
UserId     7    2
UserName Somsak 1
RegDate 2017-01-23T00:00:00 1

บาง ค่า เราใช้ Where ได้เลย

select * from OPENJSON(@v) with ( UserID int '$.UserID', UserName varchar(50) '$.UserName', RegDate datetime '$.RegDate')
ผล
UserId UserName  RegDate
7 Somsak 2017-01-23 00:00:00.000


แล้วจึงใช้ Insert หรือ Update ได้ แทน @v ลงใน $$JSON$$
    string cmdtext = "INSERT INTO [temp_Users] ([UserID],[UserName],[RegDate])"+
                "Select UserID,UserName,RegDate from OPENJSON('$$JSON$$')with ( UserID int '$.UserID', UserName varchar(50) '$.UserName', RegDate datetime '$.RegDate')";

        

ในกรณีที่ได้ ผลจาก query มาแล้วต้องการเขียนเป็นโปรแกรมแบบ Class (no sql) ก็ทำได้โดยเข้า Web
json2charp.com และ เลือก Quicktype (ใน Visual Studio ต้องลง Nuget ของ Newtonsoft ก่อน)

เช่น ผลจาก Query
[{"UserID":1,"UserName":"Phar","RegDate":"2017-01-23T00:00:00"},{"UserID":2,"UserName":"Som"},{"UserID":3,"UserName":"Cho"}]



Generate จาก json2charp.com จะได้ Class .ให้ไปเปลี่ยน Welcome  Class เอา

namespace QuickType
{
    using System;
    using System.Collections.Generic;

    using System.Globalization;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Converters;

    public partial class Welcome
    {
        [JsonProperty("UserID")]
        public long UserId { get; set; }

        [JsonProperty("UserName")]
        public string UserName { get; set; }

        [JsonProperty("RegDate", NullValueHandling = NullValueHandling.Ignore)]
        public DateTimeOffset? RegDate { get; set; }
    }

    public partial class Welcome
    {
        public static Welcome[] FromJson(string json) => JsonConvert.DeserializeObject<Welcome[]>(json, QuickType.Converter.Settings);
    }

    public static class Serialize
    {
        public static string ToJson(this Welcome[] self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings);
    }

    internal static class Converter
    {
        public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
        {
            MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
            DateParseHandling = DateParseHandling.None,
            Converters =
            {
                new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
            },
        };
    }
}

เวลาใช้ใน SQL  c# จะเป็นแบบนี้


 string connString = @"Data Source=127.0.0.1\sql_server_demo;User ID=sa;Password=???;Initial Catalog=MyDb;Integrated Security=";
           
            string cmdtext = "SELECT *  FROM [temp_Users] FOR JSON AUTO";
            using (SqlConnection conn = new SqlConnection(connString))
            {
                conn.Open();

                using (SqlCommand cmd = new SqlCommand(cmdtext, conn))
                {

                    
                   SqlDataReader rdr= cmd.ExecuteReader();

                    // Get the values
                    while (rdr.Read())
                    {
                        //listBox1.Items.Add(rdr[0]);
                        textBox1.Text =rdr[0].ToString();
                      QuickType.Welcome[] datas=  QuickType.Welcome.FromJson(textBox1.Text);
                        string username = datas[0].UserName;
                    }

                }
            }
        }

ลดเวลาในการเขียนและ Validate โปรแกรมได้มาก


วันเสาร์ที่ 7 กันยายน พ.ศ. 2562

ติดตั้ง SQL Server ด้วย docker

Microsoft ออก SQL Server linux ใช้งาน ง่ายมาก
ติดตั้ง Docker แล้วเลือกติดตั้ง sqlserver Linux แล้ว start docker ก่อน

docker pull microsoft/mssql-server-linux
docker ps -a จะได้ <Key> เป็นตัวเลข
docker run -d --name sql_server_demo -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=Your_Password' -p 1433:1433 microsoft/mssql-server-linux

docker cp <Path>you_database.mdf <key>:/var/opt/mssql/data

แล้ว ลง SQL Server Management
เลือก attach database

ปิด Service
docker container stop sql_server_demo