From 3e75bdc9b9bf763c0290de8b652c51d9b1b93f75 Mon Sep 17 00:00:00 2001 From: Msystech Date: Fri, 21 Aug 2026 09:27:27 +0900 Subject: [PATCH] =?UTF-8?q?=EC=BF=BC=EB=A6=AC=20=ED=8E=B8=EC=A7=91?= =?UTF-8?q?=EA=B8=B0=20=E2=80=94=20=EB=AC=B4=EC=97=87=EC=9D=84=20=EB=8F=8C?= =?UTF-8?q?=EB=A0=B8=EB=8A=94=EC=A7=80,=20=EC=BB=AC=EB=9F=BC=EC=9D=B4=20?= =?UTF-8?q?=EB=AC=B4=EC=97=87=EC=9D=B8=EC=A7=80,=20=EB=8A=98=20=EB=9C=A8?= =?UTF-8?q?=EB=8A=94=20=EA=B2=BD=EA=B3=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 돌린 SQL 을 창 안에서 볼 수 있다 치환을 마친 문장을 필드에 담아 두기만 하고(진단용) 화면에는 안 내보냈다. 0행이 나왔을 때 치환이 NULL 이라 조건이 사라진 것인지 이 환자에게 자료가 없는 것인지 가르는 유일한 수단이 그 문장인데, 볼 방법이 없었다. 요약 줄에 '돌린 SQL 보기' 를 두고 읽기 전용으로 펼친다(SQL 복사도 함께 — 데이터소스 결과 창과 같은 구성이다). 실패했으면 자동으로 펼친다 — 표가 어차피 없고, 오라클 오류 문구만으로는 어디가 틀렸는지 알 수 없다. ## 0행이어도 컬럼 머리글을 남긴다 전에는 0행이면 표를 통째로 접었다. 그런데 컬럼 이름은 이미 알고 있고, 그것이 배선 필드 칸에 옮겨 적을 값이다. 접어 버리면 방금 조회한 컬럼명을 알아내려고 쿼리를 또 돌려야 한다 — 0행은 배선 작업에서 드문 상태도 아니다. ## 늘 뜨던 경고를 조건부로 '변수 NULL — 구문만 검사' 가 치환 대상이 하나도 없는 쿼리에도 붙었다. 치환할 것이 없으니 NULL 로 바뀐 것도 없는데 거짓 꼬리표가 상시로 달려서, 정작 진짜 경고가 붙은 날에도 눈에 들어오지 않았다. 늘 뜨는 경고는 경고가 아니다. 치환 시도가 실제로 있었을 때만 붙인다. ## 같은 창이 진입 경로에 따라 달랐다 데이터소스 아이콘에서 편집기를 열면 《컨트롤명》 치환 칩이 나오는데 인스펙터의 쿼리 행에서 열면 그 칩이 통째로 사라졌다 — 호출부가 컨트롤 이름을 안 넘겼다. 같은 창이 어디서 열렸는지에 따라 능력이 다르면 안 된다. 인스펙터도 넘기게 했다. ## 판정 - 단위 시험 388 · edit-smoke 405건 전건 통과 - --query-popup(자동완성 팝업 진단) 전건 통과 - --dialog-shots 69장 전건 통과 — 03b 샷에서 치환 변수 없는 쿼리의 거짓 꼬리표가 사라진 것을 눈으로 확인했다 - --modal-check · --maxrect · --scale-budget 전건 통과 - --db-render P062 md5 8d683835f5d81e7bb41c79071d6bf954 불변 '돌린 SQL' 펼침과 실패 시 자동 펼침은 DB 가 붙은 단말에서 실제 실패 쿼리로 한 번 확인하는 것이 좋다 — 진단은 성공 경로만 찍는다. Co-Authored-By: Claude Fable 5 --- .../Inspector/InspectorViewModel.cs | 35 ++++++++++++++- .../ViewModels/Inspector/PropertyRows.cs | 13 +++++- .../Views/QueryEditorWindow.xaml | 24 ++++++++++ .../Views/QueryEditorWindow.xaml.cs | 45 ++++++++++++++++++- 4 files changed, 113 insertions(+), 4 deletions(-) diff --git a/src/SheetMe.Designer/ViewModels/Inspector/InspectorViewModel.cs b/src/SheetMe.Designer/ViewModels/Inspector/InspectorViewModel.cs index e221c5b..6c20d59 100644 --- a/src/SheetMe.Designer/ViewModels/Inspector/InspectorViewModel.cs +++ b/src/SheetMe.Designer/ViewModels/Inspector/InspectorViewModel.cs @@ -922,7 +922,9 @@ public sealed class InspectorViewModel : ViewModelBase PropEditorKind.DataActionTag => new TagPickerRowViewModel(def.Label, "액션 태그 선택 — 더블클릭/버튼 액션(EN_DataActionTyp)", LegacyTagCatalog.DataActionTags, LegacyTagUsageCatalog.SuggestFor(def.Key, controlType)) { IsActionTag = true }, - PropEditorKind.SqlQuery => new QueryRowViewModel(def.Label), + // 컨트롤 이름을 넘긴다 — 안 넘기면 인스펙터로 연 편집기에서만 《컨트롤명》 칩이 사라져 + // 같은 창이 진입 경로에 따라 능력이 달라진다 + PropEditorKind.SqlQuery => new QueryRowViewModel(def.Label) { ControlNamesOf = ControlNames }, PropEditorKind.Mask => new MaskRowViewModel(def.Label), // 배선 대상 목록은 '지금 이 서식'의 데이터소스다 — 런타임도 같은 서식 안에서만 이름을 찾는다 PropEditorKind.DataTableField => new DataTableFieldRowViewModel(def.Label, DataTableNames), @@ -953,6 +955,37 @@ public sealed class InspectorViewModel : ViewModelBase /// 레거시 편집기는 열려 있는 모든 디자인 서피스를 훑어 다른 서식의 데이터소스까지 섞어 보여 주고, /// 그걸 고르면 런타임에 조용히 실패한다(bzMDataTableField.vb:18-63). 우리는 현재 문서로 한정한다. /// + /// + /// 이 서식의 모든 컨트롤 이름 — 쿼리 편집기의 《컨트롤명》 치환 후보다. + /// + /// 데이터소스 아이콘에서 편집기를 열면 이 목록이 넘어가는데 인스펙터의 쿼리 행에서는 + /// 안 넘어가서, 같은 창이 진입 경로에 따라 능력이 달랐다. + /// + private IReadOnlyList ControlNames() + { + var names = new List(); + void Visit(SheetMe.Core.Models.ControlElement element) + { + if (element.Id.Length > 0) + { + names.Add(element.Id); + } + foreach (var child in element.Children) + { + Visit(child); + } + } + foreach (var page in designer.Document.Pages) + { + foreach (var control in page.Controls) + { + Visit(control); + } + } + names.Sort(StringComparer.Ordinal); + return names; + } + private IReadOnlyList DataTableNames() { var names = new List(); diff --git a/src/SheetMe.Designer/ViewModels/Inspector/PropertyRows.cs b/src/SheetMe.Designer/ViewModels/Inspector/PropertyRows.cs index 23c91e9..f8df160 100644 --- a/src/SheetMe.Designer/ViewModels/Inspector/PropertyRows.cs +++ b/src/SheetMe.Designer/ViewModels/Inspector/PropertyRows.cs @@ -782,9 +782,20 @@ public sealed class QueryRowViewModel : PropertyRowViewModel protected override void OnValueApplied() => OnPropertyChanged(nameof(Summary)); + /// + /// 이 서식의 컨트롤 이름 — 편집기의 《컨트롤명》 치환 후보가 된다. + /// + /// 안 넘기면 같은 창이 진입 경로에 따라 능력이 달라진다 — + /// 데이터소스 아이콘에서 열면 컨트롤 변수 칩이 나오는데 + /// 인스펙터의 쿼리 행에서 열면 그 칩이 통째로 사라졌다. + /// 목록은 문서마다 다르므로 카탈로그가 아니라 호출부가 준다. + /// + public Func>? ControlNamesOf { get; init; } + private void OnEdit() { - var dialog = new Views.QueryEditorWindow(Label, ValueText) + var dialog = new Views.QueryEditorWindow(Label, ValueText, + showVariables: true, controlNames: ControlNamesOf?.Invoke()) { Owner = System.Windows.Application.Current.MainWindow, }; diff --git a/src/SheetMe.Designer/Views/QueryEditorWindow.xaml b/src/SheetMe.Designer/Views/QueryEditorWindow.xaml index 9ef8c4e..ec3657f 100644 --- a/src/SheetMe.Designer/Views/QueryEditorWindow.xaml +++ b/src/SheetMe.Designer/Views/QueryEditorWindow.xaml @@ -323,9 +323,33 @@