private static void OnGUIRow(RowDef rowDef) { switch (rowDef.Type) { case RowType.Header: GUILayout.Label(rowDef.Col1, Styles.HeaderFont); break; case RowType.Row: GUILayout.BeginHorizontal(); GUILayout.Label(rowDef.Col1, Styles.RowTitleFont, _minTitleWidth); GUILayout.Label(rowDef.Col2(), Styles.RowFont); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); break; } }
private void DELETE(RowDef pkrow, RowDef[] fkrows, string locator, StringBuilder builder) { if (fkrows.Length == 0) return; foreach (var row in fkrows) { string sql = string.Format("[{0}] IN (SELECT [{1}] FROM {2} WHERE {3})", row.fkColumn, pkrow.pkColumn, pkrow.fkTable.FormalName, locator); RowDef[] getFkRows = GetFkRows(row.fkTable); DELETE(row, getFkRows, sql, builder); builder.AppendLine(deleteTemplate(row, locator)); } }
private string selectTemplate(RowDef pkrow, RowDef fkrow) { return string.Format("SELECT [{0}] FROM {1} WHERE [{2}] = @{3}", fkrow.pkColumn, fkrow.pkTable.FormalName, fkrow.fkColumn, pkrow.pkColumn); }
private string deleteTemplate(RowDef row, string locator) { return string.Format("DELETE FROM {0} WHERE [{1}] IN (SELECT [{2}] FROM {3} WHERE {4})", row.fkTable.FormalName, row.fkColumn, row.pkColumn, row.pkTable.FormalName, locator); }
public async Task <ImportResult> ImportAsync(string csvPath, ImportMethod method, CancellationToken?token, IProgress <int> progress) { IEnumerable <TModel> original = (LoadAsync == null) ? Enumerable.Empty <TModel>() : await LoadAsync(); if (token?.IsCancellationRequested ?? false) { return(null); } progress?.Report(20); // 進捗:取込対象データ読込完了 var unitOfWork = new UnitOfWorkWithReference <TModel, TIdentity>( original, createIdentity); var worker = new ImportWorker <TModel>(RowDef); worker.LoginUserId = UserId; worker.LoginUserCode = UserCode; worker.LoginCompanyId = CompanyId; worker.LoginCompanyCode = CompanyCode; await InitializeWorker?.Invoke(worker); var valid = true; var csv = Parser.Parse(csvPath); RowDef.SetupFields(); var fieldDefs = RowDef.Fields .Where(f => !f.Ignored) .OrderBy(f => f.FieldNumber) .ToArray(); foreach (var fields in csv.Skip(RowDef.StartLineNumber)) { worker.NewRecord(fields); if (fields.Length < fieldDefs.Length) { foreach (var field in fieldDefs.Skip(fields.Length)) { Errors.Add(new WorkingReport { LineNo = worker.RecordCount, FieldNo = field.FieldIndex, FieldName = field.FieldName, Value = string.Empty, Message = $"{field.FieldName}がありません。", }); } } valid &= RowDef.Do(worker); // 書式チェック&エラー情報収集 if (worker.Reports.Any()) { Errors.AddRange(worker.Reports); worker.Reports.Clear(); } } progress?.Report(40); // 進捗:CSVファイル読込完了 // DB関連チェック var validate = new CodeToIdWorker <TModel>(worker); // importの結果を引き渡す valid &= RowDef.Do(validate); // DBチェック&エラー情報収集 Errors.AddRange(validate.Reports); await AdditionalWorker?.Invoke(worker); var additionalValidate = new AdditionalValidationWorker <TModel>(worker) { ImportMethod = method, }; valid &= RowDef.Do(additionalValidate); // DBチェック&エラー情報収集 Errors.AddRange(additionalValidate.Reports); foreach (var lineNo in Errors.Where(x => x.LineNo.HasValue).Select(x => x.LineNo.Value).Distinct()) { worker.Models.Remove(lineNo); } // DB重複チェック if (!method.ValidateDuplicated(unitOfWork, worker)) { worker.Reports.ForEach(r => worker.Models.Remove(r.LineNo.Value)); Errors.AddRange(worker.Reports); worker.Reports.Clear(); } // ファイル内キー重複チェック var uniqueKeys = new Dictionary <TIdentity, int>(); var duplicatedLines = new List <int>(); foreach (var pair in validate.Models) { // 必須項目が空欄の時は、Nullまたはゼロになっている。 // キー項目が部分的にでも空欄の場合、重複チェックをパスする。 var identity = createIdentity(pair.Value); if (ContainsNull(identity)) { identity = default(TIdentity); } if (identity == null || identity.Equals(default(TIdentity))) { continue; } if (uniqueKeys.ContainsKey(identity)) { switch (RowDef.DuplicateAdoption) { case DuplicateAdoption.BothAreErrors: var duplicated = uniqueKeys[identity]; if (!duplicatedLines.Contains(duplicated)) { duplicatedLines.Add(duplicated); } duplicatedLines.Add(pair.Key); break; case DuplicateAdoption.First: duplicatedLines.Add(pair.Key); break; } } else { uniqueKeys.Add(identity, pair.Key); } if (token.HasValue && token.Value.IsCancellationRequested) { return(null); } } progress?.Report(60); // 進捗:データベース関連チェック完了 switch (RowDef.TreatDuplicateAs) { case TreatDuplicateAs.Error: duplicatedLines.ForEach(lineNo => { Errors.Add(new WorkingReport() // キー重複 { LineNo = lineNo, FieldName = RowDef.KeyFields?.FirstOrDefault().FieldName ?? string.Empty, Message = "重複しているため、インポートできません。", Value = createIdentity(validate.Models[lineNo]).ToString(), }); }); break; case TreatDuplicateAs.Ignore: // エラーにはせず、ここで取込対象から取り除く。 duplicatedLines.ForEach(lineNo => worker.Ignore(lineNo)); break; } if (token.HasValue && token.Value.IsCancellationRequested) { return(null); } // エラーデータを更新対象から取り除く var errorLines = Errors .GroupBy(report => report.LineNo) .Select(g => g.Key) .ToList(); if (errorLines.Any(lineNo => !lineNo.HasValue)) { validate.Models.Clear(); } else { errorLines.ForEach(lineNo => validate.Models.Remove(lineNo.Value)); } if (token.HasValue && token.Value.IsCancellationRequested) { return(null); } progress?.Report(80); // 進捗:すべてのデータチェック完了 ImportResult result = null; if (method.Import(unitOfWork, worker) && RegisterAsync != null) { result = await RegisterAsync(unitOfWork); PostImportHanlder?.Invoke(worker, result); Debug.Assert(result != null, $"{nameof(RegisterAsync)}()が{nameof(ImportResult)}を返しませんでした。"); } else // 登録処理をしなかった、または取込可能件数がゼロ { result = new ImportResult { ProcessResult = new ProcessResult { Result = true }, InsertCount = 0, UpdateCount = 0, DeleteCount = 0, }; } Errors.AddRange(worker.Reports); if (Errors.Any() && !string.IsNullOrWhiteSpace(ErrorLogPath)) { OutputErrorLog(ErrorLogPath, Errors, csvPath); } result.ValidItemCount = worker.Models.Count; result.InvalidItemCount = worker.RecordCount - result.ValidItemCount; UnitOfWork = unitOfWork; progress?.Report(100); // 進捗:取込完了 return(result); }
public void Build() => this.Content( Grid() .RowDefs(RowDef.Height(72), RowDef.Height(30), RowDef.Height(385), RowDef.Height(80)) .Childs( TextBlock() .Foreground(SolidBrush("#ff000000")) .Font(family: "SegoeUI", size: 20, style: FontStyles.Normal, weight: FontWeights.SemiBold) .Text("SAMPLE DIALOG FOR UIExt.Markup.WPF") .HAlignCenter() .LineHeight(24) .Row(0) .Margin(24), Grid() .ColDefs(ColDef, ColDef, ColDef) .Row(1) .Childs( ToggleButton() .Content("Toggle text visibility") .Command(ViewModel.ToggleTextVisibilityCommand) .Column(0), TextBlock() .Column(1) .Foreground(Brushes.Red) .VAlignCenter() .HAlignCenter() .Text("Some additional text") .Bind( VisibilityProperty, Binding(nameof(ViewModel.AdditionalTextVisible), Converters.BoolToVisibilityConverter)), TextBlock() .Column(2) .Foreground(Brushes.Green) .VAlignCenter() .HAlignCenter() .Text("Some another additional text") .Bind( VisibilityProperty, Binding(nameof(ViewModel.AdditionalTextVisible), Converters.InvertBoolToVisibilityConverter))), TextBox() .FocusStyleNone() .Margin(24, 0, 24, 0) .Border(1) .BorderBrush(Black) .Wrap() .Row(2) .Font("SegoeUI") .FontSize(14) .ReadOnly() .Text("SOme text") .VScrollAuto() .HScrollAuto(), Grid() .Row(3) .ColDefs(ColDef, ColDef) .Childs( Button() .Content("ACTION") .Name("ActionButton") .Style(_accentDialogButtonStyle) .Height(32) .Width(145) .HAlignRight() .Column(0) .Margin(24, 24, 3, 24) .Command(ViewModel.ActionCommand), Button() .Content("EXIT") .Name("ExitButton") .Style(_dialogButtonStyle) .Height(32) .Width(145) .HAlignLeft() .Column(1) .Margin(3, 24, 24, 24) .Command(ViewModel.ExitCommand))));
public async Task <int> ExportAsync(string csvPath, List <TModel> original, CancellationToken cancel, IProgress <int> progress, Action <StringBuilder> specialHeaderHandler = null) { if (cancel.IsCancellationRequested) { return(0); } progress.Report(20); // 進捗:取込対象データ読込完了 var export = new ExportWorker <TModel>(RowDef.DataExpression); export.LoginUserId = UserId; export.LoginUserCode = UserCode; export.LoginCompanyId = CompanyId; export.LoginCompanyCode = CompanyCode; RowDef.SetupFields(); var sb = new StringBuilder(); specialHeaderHandler?.Invoke(sb); // header var header = RowDef.GetHeaderAry(); if (header != null) { sb.AppendLine(string.Join(RowDef.Delimiter, header)); } await Task.Run(() => { foreach (TModel m in original) { export.NewRecord(m); RowDef.Do(export); } }, cancel); // DB関連チェック var validate = new IdToCodeWorker <TModel>(export); // Exportの結果を引き渡す RowDef.Do(validate); // DBチェック&エラー情報収集 // TODO: 文字列項目は強制でダブルクォート という要件 await Task.Run(() => { foreach (var record in validate.Records.Values) { for (int i = 0; i < record.Count; i++) { if (record[i] == null) { continue; } if (record[i].IndexOf("\"") >= 0 || record[i].IndexOf(RowDef.Delimiter) >= 0 || record[i].IndexOf("\r") >= 0 || record[i].IndexOf("\n") >= 0) { record[i] = "\"" + record[i].Replace("\"", "\"\"") + "\""; } } sb.AppendLine(string.Join(RowDef.Delimiter, record.ToArray())); } }); try { File.WriteAllText(csvPath, sb.ToString(), CsvEncoding); } catch (Exception e) { Exception = e; return(0); } return(validate.Records.Count); }