diff --git a/Readme.md b/Readme.md index 9e1d22a..23c5e7d 100644 --- a/Readme.md +++ b/Readme.md @@ -188,10 +188,17 @@ xlsx -> yaml (from) 変換で出力するseedファイルをID単位ごとに分 分割しておくと、複数人で同時に別のIDのデータを編集してコミットする等の場合に、コンフリクトがおこりにくくなります。 -`(前削除桁数:)(xlsxファイル名/)seedテーブル名(:後削除桁数)(@fromまたは@to)(@key=プライマリキー名)`の形式で指定します。(複数指定はコマンドラインでは`,`区切り・GUIでは改行区切り) +`(前削除桁数:)(xlsxファイル名/)seedテーブル名(:後削除桁数)(@その他のオプション)`の形式で指定します。(複数指定はコマンドラインでは`,`区切り・GUIでは改行区切り) xlsxファイル名を指定する場合はパスを含まずファイル名のみ(path/to/foo.xlsxではなくfoo.xlsx)で指定してください。 +その他のオプション: + +- @fromまたは@to: それぞれxlsx -> yaml (from) 変換、yaml -> xlsx (to) 変換のみでそのオプションが有効になります +- @key=プライマリキー名: プライマリキーを"id"以外にします +- @column-names-row=数値: --column-names-row をテーブル個別指定 +- @data-start-row=数値: --data-start-row をテーブル個別指定 + ID(プライマリキーを指定した場合はそのカラム)数値の桁を上の方から前削除桁数分、下の方から後削除桁数分削ったものがファイル名として使われます。 例: diff --git a/seedtable-test/SubdivideOptionTest.cs b/seedtable-test/SubdivideOptionTest.cs index 55d3e31..c3af985 100644 --- a/seedtable-test/SubdivideOptionTest.cs +++ b/seedtable-test/SubdivideOptionTest.cs @@ -11,24 +11,26 @@ namespace seedtable_test { public class SubdivideOptionTest { public static IEnumerable Examples() { - yield return new object[] { "foos", "NO_NAME", "foos", false, 0, 0, "id", OnOperation.From | OnOperation.To }; - yield return new object[] { "foo.xlsx/foos", "foo.xlsx", "foos", false, 0, 0, "id", OnOperation.From | OnOperation.To }; - yield return new object[] { "foos:0", "NO_NAME", "foos", true, 0, 0, "id", OnOperation.From | OnOperation.To }; - yield return new object[] { "0:foos", "NO_NAME", "foos", true, 0, 0, "id", OnOperation.From | OnOperation.To }; - yield return new object[] { "foos:1", "NO_NAME", "foos", true, 0, 1, "id", OnOperation.From | OnOperation.To }; - yield return new object[] { "1:foos", "NO_NAME", "foos", true, 1, 0, "id", OnOperation.From | OnOperation.To }; - yield return new object[] { "2:foos:2", "NO_NAME", "foos", true, 2, 2, "id", OnOperation.From | OnOperation.To }; - yield return new object[] { "foos@NO_OPTION", "NO_NAME", "foos", false, 0, 0, "id", OnOperation.From | OnOperation.To }; - yield return new object[] { "foos@from", "NO_NAME", "foos", false, 0, 0, "id", OnOperation.From }; - yield return new object[] { "foos@TO", "NO_NAME", "foos", false, 0, 0, "id", OnOperation.To }; - yield return new object[] { "foos@key=foo_id", "NO_NAME", "foos", false, 0, 0, "foo_id", OnOperation.From | OnOperation.To }; - yield return new object[] { "foos@from@key=foo_id", "NO_NAME", "foos", false, 0, 0, "foo_id", OnOperation.From }; - yield return new object[] { "1:foo.xlsx/foos:0@from@key=foo_id", "foo.xlsx", "foos", true, 1, 0, "foo_id", OnOperation.From }; + yield return new object[] { "foos", "NO_NAME", "foos", false, 0, 0, "id", null, null, OnOperation.From | OnOperation.To }; + yield return new object[] { "foo.xlsx/foos", "foo.xlsx", "foos", false, 0, 0, "id", null, null, OnOperation.From | OnOperation.To }; + yield return new object[] { "foos:0", "NO_NAME", "foos", true, 0, 0, "id", null, null, OnOperation.From | OnOperation.To }; + yield return new object[] { "0:foos", "NO_NAME", "foos", true, 0, 0, "id", null, null, OnOperation.From | OnOperation.To }; + yield return new object[] { "foos:1", "NO_NAME", "foos", true, 0, 1, "id", null, null, OnOperation.From | OnOperation.To }; + yield return new object[] { "1:foos", "NO_NAME", "foos", true, 1, 0, "id", null, null, OnOperation.From | OnOperation.To }; + yield return new object[] { "2:foos:2", "NO_NAME", "foos", true, 2, 2, "id", null, null, OnOperation.From | OnOperation.To }; + yield return new object[] { "foos@NO_OPTION", "NO_NAME", "foos", false, 0, 0, "id", null, null, OnOperation.From | OnOperation.To }; + yield return new object[] { "foos@from", "NO_NAME", "foos", false, 0, 0, "id", null, null, OnOperation.From }; + yield return new object[] { "foos@TO", "NO_NAME", "foos", false, 0, 0, "id", null, null, OnOperation.To }; + yield return new object[] { "foos@key=foo_id", "NO_NAME", "foos", false, 0, 0, "foo_id", null, null, OnOperation.From | OnOperation.To }; + yield return new object[] { "foos@column-names-row=9", "NO_NAME", "foos", false, 0, 0, "id", 9, null, OnOperation.From | OnOperation.To }; + yield return new object[] { "foos@data-start-row=10", "NO_NAME", "foos", false, 0, 0, "id", null, 10, OnOperation.From | OnOperation.To }; + yield return new object[] { "foos@from@key=foo_id", "NO_NAME", "foos", false, 0, 0, "foo_id", null, null, OnOperation.From }; + yield return new object[] { "1:foo.xlsx/foos:0@from@key=foo_id@column-names-row=9", "foo.xlsx", "foos", true, 1, 0, "foo_id", 9, null, OnOperation.From }; } [Theory] [MemberData(nameof(Examples))] - public void Parse(string subdivideStr, string fileName, string sheetName, bool needSubdivide, int cutPrefix, int cutPostfix, string keyColumnName, OnOperation oonOperation) { + public void Parse(string subdivideStr, string fileName, string sheetName, bool needSubdivide, int cutPrefix, int cutPostfix, string keyColumnName, int? columnNamesRow, int? dataStartRow, OnOperation oonOperation) { var subdivide = SheetNameWithSubdivide.FromMixed(subdivideStr); Assert.True(subdivide.FileName.IsMatch(fileName)); Assert.True(subdivide.SheetName.IsMatch(sheetName)); @@ -36,6 +38,8 @@ public void Parse(string subdivideStr, string fileName, string sheetName, bool n Assert.Equal(subdivide.CutPrefix, cutPrefix); Assert.Equal(subdivide.CutPostfix, cutPostfix); Assert.Equal(subdivide.KeyColumnName, keyColumnName); + Assert.Equal(subdivide.ColumnNamesRow, columnNamesRow); + Assert.Equal(subdivide.DataStartRow, dataStartRow); Assert.Equal(subdivide.OnOperation, oonOperation); } } diff --git a/seedtable/SeedTableInterface.cs b/seedtable/SeedTableInterface.cs index 81451a8..c7fd6b7 100644 --- a/seedtable/SeedTableInterface.cs +++ b/seedtable/SeedTableInterface.cs @@ -185,7 +185,7 @@ static DateTime ExcelToSeedCore(IExcelData excelData, string file, FromOptions o } static SeedTableBase GetSeedTable(IExcelData excelData, string sheetName, CommonOptions options, SheetNameWithSubdivide subdivide) { - var seedTable = excelData.GetSeedTable(sheetName, options.columnNamesRow, options.dataStartRow, options.ignoreColumns, subdivide.KeyColumnName, options.versionColumn); + var seedTable = excelData.GetSeedTable(sheetName, subdivide.ColumnNamesRow ?? options.columnNamesRow, subdivide.DataStartRow ?? options.dataStartRow, options.ignoreColumns, subdivide.KeyColumnName, options.versionColumn); if (seedTable.Errors.Count != 0) { var skipExceptions = seedTable.Errors.Where(error => error is NoIdColumnException); if (skipExceptions.Count() != 0) { diff --git a/seedtable/SheetNameWithSubdivide.cs b/seedtable/SheetNameWithSubdivide.cs index 35bdc92..6201fc2 100644 --- a/seedtable/SheetNameWithSubdivide.cs +++ b/seedtable/SheetNameWithSubdivide.cs @@ -14,17 +14,23 @@ public static SheetNameWithSubdivide FromMixed(string mixedName) { var options = result.Groups[5].Value == null ? new string[] { } : result.Groups[5].Value.Split('@'); var onOperation = OnOperation.From | OnOperation.To; var keyColumnName = "id"; + int? columnNamesRow = null; + int? dataStartRow = null; foreach (var option in options) { if (Regex.IsMatch(option, $"^(?:from|to)$", RegexOptions.IgnoreCase)) { Enum.TryParse(option, true, out onOperation); } else if (option.StartsWith("key=")) { keyColumnName = option.Substring(4); + } else if (option.StartsWith("column-names-row=")) { + columnNamesRow = int.Parse(option.Substring(17)); + } else if (option.StartsWith("data-start-row=")) { + dataStartRow = int.Parse(option.Substring(15)); } } var needSubdivide = cutPrefixStr.Length != 0 || cutPostfixStr.Length != 0; var cutPrefix = cutPrefixStr.Length == 0 ? 0 : Convert.ToInt32(cutPrefixStr); var cutPostfix = cutPostfixStr.Length == 0 ? 0 : Convert.ToInt32(cutPostfixStr); - return new SheetNameWithSubdivide(fileName, sheetName, needSubdivide, cutPrefix, cutPostfix, keyColumnName, onOperation); + return new SheetNameWithSubdivide(fileName, sheetName, needSubdivide, cutPrefix, cutPostfix, keyColumnName, columnNamesRow, dataStartRow, onOperation); } public Wildcard FileName { get; } = null; @@ -33,6 +39,8 @@ public static SheetNameWithSubdivide FromMixed(string mixedName) { public int CutPrefix { get; } public int CutPostfix { get; } public string KeyColumnName { get; } + public int? ColumnNamesRow { get; } + public int? DataStartRow { get; } public OnOperation OnOperation { get; } public SheetNameWithSubdivide( @@ -42,6 +50,8 @@ public SheetNameWithSubdivide( int cutPrefix = 0, int cutPostfix = 0, string keyColumnName = "id", + int? columnNamesRow = null, + int? dataStartRow = null, OnOperation onOperation = OnOperation.From | OnOperation.To ) { FileName = new Wildcard(fileName); @@ -50,6 +60,8 @@ public SheetNameWithSubdivide( CutPrefix = cutPrefix; CutPostfix = cutPostfix; KeyColumnName = keyColumnName; + ColumnNamesRow = columnNamesRow; + DataStartRow = dataStartRow; OnOperation = onOperation; }