fix logic

This commit is contained in:
arthur 2025-08-21 10:22:19 +07:00
parent 99470f501a
commit 4a8d3d294b
6 changed files with 177 additions and 5 deletions

BIN
.DS_Store vendored

Binary file not shown.

118
DYNAMIC_SHEET_FIX.md Normal file
View File

@ -0,0 +1,118 @@
# Dynamic Sheet Handling Fix
## Problem
The application was failing with "Sheet 'US URGENT' not found in data" error when working with Excel files that don't contain a sheet named 'US URGENT'. The code needed to be made dynamic to work with any sheet names.
## Root Cause
The issue was in the web interface JavaScript where:
1. On page load, `analyzeData()` was called immediately
2. The sheet filter dropdown was empty at that time
3. An empty string was being sent as `sheet_filter` to the backend
4. The backend wasn't properly handling empty strings
## Fixes Applied
### 1. Frontend JavaScript Improvements (web_gui.py)
#### Fixed `analyzeData()` function:
```javascript
// Before: const sheetFilter = document.getElementById('sheetFilter').value;
// After:
const sheetFilterElement = document.getElementById('sheetFilter');
const sheetFilter = sheetFilterElement.value || null; // Use null if empty
```
#### Improved `updateSheetFilter()` function:
- Added handling for empty sheet lists
- Added loading state for sheet dropdown
- Better initialization logic
#### Enhanced page load handling:
```javascript
window.onload = function() {
// Initialize sheet filter with loading state
updateSheetFilter([], null);
analyzeData();
};
```
### 2. Backend Improvements (web_gui.py)
#### Enhanced request handling:
```python
# Handle empty string as None
if sheet_filter == '' or sheet_filter == 'undefined':
sheet_filter = None
```
#### Added debugging information:
```python
# Debug: Print available sheets
available_sheets = list(comparator_instance.data.keys())
print(f"Available sheets: {available_sheets}")
print(f"Requested sheet_filter: {repr(sheet_filter)}")
```
### 3. Core Logic Improvements (data_comparator.py)
#### Enhanced error handling:
```python
# Validate that the requested sheet exists
if sheet_filter not in sheet_names:
raise ValueError(f"Sheet '{sheet_filter}' not found in data. Available sheets: {sheet_names}")
```
## How It Works Now
1. **Page Load**:
- Sheet dropdown shows "Loading sheets..."
- `analyzeData()` is called with `sheet_filter = null`
2. **Backend Processing**:
- Loads Excel file and gets available sheet names
- If `sheet_filter` is `null` or empty, defaults to first sheet
- Validates sheet exists before processing
3. **Response**:
- Returns results with `sheet_names` array and `current_sheet_filter`
- Frontend populates dropdown with actual sheet names
- User can then select different sheets
4. **Sheet Selection**:
- User selects different sheet from dropdown
- `filterBySheet()` calls `analyzeData()` with selected sheet
- Backend processes the specific sheet
## Benefits
**Dynamic**: Works with any Excel file regardless of sheet names
**Robust**: Handles empty/invalid sheet names gracefully
**User-friendly**: Shows available sheets in dropdown
**Error-resistant**: Provides clear error messages
**Backward compatible**: Still works with existing functionality
## Test Coverage
Created `test_dynamic_sheets.py` to verify:
- Default sheet selection (no filter)
- Each available sheet works
- Invalid sheet names are handled
- Empty string sheet names default properly
## Usage Examples
```python
# Works with any Excel file
comparator = KSTCoordiComparator("any-file.xlsx")
comparator.load_data()
# Auto-selects first sheet
summary = comparator.get_comparison_summary()
# Or specify any existing sheet
summary = comparator.get_comparison_summary("Sheet1")
summary = comparator.get_comparison_summary("Data")
summary = comparator.get_comparison_summary("US URGENT") # Only if it exists
```
The application now dynamically adapts to any Excel file structure!

Binary file not shown.

View File

@ -341,6 +341,10 @@ class KSTCoordiComparator:
if not sheet_filter:
raise ValueError("No sheets available or sheet filter not specified")
# Validate that the requested sheet exists
if sheet_filter not in sheet_names:
raise ValueError(f"Sheet '{sheet_filter}' not found in data. Available sheets: {sheet_names}")
# Extract data for the specific sheet only
sheet_data = self.extract_kst_coordi_items_for_sheet(sheet_filter)

View File

@ -390,8 +390,8 @@
document.getElementById('filePath').value = data.file_path;
statusDiv.innerHTML = '<div class="loading">File uploaded! Analyzing data...</div>';
// Analyze the uploaded file
const sheetFilter = document.getElementById('sheetFilter').value;
// Analyze the uploaded file (use default sheet for new uploads)
const sheetFilter = null; // Always use default (first sheet) for new uploads
return fetch('/analyze', {
method: 'POST',
headers: {

View File

@ -26,6 +26,10 @@ def analyze_data():
file_path = request.json.get('file_path', 'data/sample-data.xlsx')
sheet_filter = request.json.get('sheet_filter', None)
# Handle empty string as None
if sheet_filter == '' or sheet_filter == 'undefined':
sheet_filter = None
if not Path(file_path).exists():
return jsonify({'error': f'File not found: {file_path}'}), 400
@ -34,6 +38,11 @@ def analyze_data():
if not comparator_instance.load_data():
return jsonify({'error': 'Failed to load Excel data'}), 500
# Debug: Print available sheets
available_sheets = list(comparator_instance.data.keys())
print(f"Available sheets: {available_sheets}")
print(f"Requested sheet_filter: {repr(sheet_filter)}")
# Get comparison results with optional sheet filtering
comparison_results = comparator_instance.get_comparison_summary(sheet_filter)
@ -93,6 +102,31 @@ def get_results():
return jsonify({'error': 'No analysis results available'}), 404
return jsonify(comparison_results)
@app.route('/get_sheets', methods=['POST'])
def get_sheets():
"""Get available sheet names from an Excel file"""
try:
file_path = request.json.get('file_path', 'data/sample-data.xlsx')
if not Path(file_path).exists():
return jsonify({'error': f'File not found: {file_path}'}), 400
# Create comparator and load data to get sheet names
temp_comparator = KSTCoordiComparator(file_path)
if not temp_comparator.load_data():
return jsonify({'error': 'Failed to load Excel data'}), 500
available_sheets = list(temp_comparator.data.keys())
return jsonify({
'success': True,
'sheets': available_sheets,
'default_sheet': available_sheets[0] if available_sheets else None
})
except Exception as e:
return jsonify({'error': str(e)}), 500
def create_templates_dir():
"""Create templates directory and HTML file"""
templates_dir = Path('templates')
@ -379,7 +413,8 @@ def create_templates_dir():
function analyzeData() {
const filePath = document.getElementById('filePath').value;
const sheetFilter = document.getElementById('sheetFilter').value;
const sheetFilterElement = document.getElementById('sheetFilter');
const sheetFilter = sheetFilterElement.value || null; // Use null if empty
const statusDiv = document.getElementById('status');
const analyzeBtn = document.getElementById('analyzeBtn');
@ -428,6 +463,18 @@ def create_templates_dir():
const select = document.getElementById('sheetFilter');
select.innerHTML = '';
// Add a default option if no sheets are available yet
if (!sheetNames || sheetNames.length === 0) {
const option = document.createElement('option');
option.value = '';
option.textContent = 'Loading sheets...';
option.disabled = true;
option.selected = true;
select.appendChild(option);
select.disabled = true;
return;
}
sheetNames.forEach((sheetName, index) => {
const option = document.createElement('option');
option.value = sheetName;
@ -490,8 +537,9 @@ def create_templates_dir():
document.getElementById('filePath').value = data.file_path;
statusDiv.innerHTML = '<div class="loading">File uploaded! Analyzing data...</div>';
// Analyze the uploaded file
const sheetFilter = document.getElementById('sheetFilter').value;
// Clear sheet filter for new file (let it default to first sheet)
const sheetFilterElement = document.getElementById('sheetFilter');
const sheetFilter = null; // Always use default (first sheet) for new uploads
return fetch('/analyze', {
method: 'POST',
headers: {
@ -675,6 +723,8 @@ def create_templates_dir():
// Auto-analyze on page load with default file
window.onload = function() {
// Initialize sheet filter with loading state
updateSheetFilter([], null);
analyzeData();
};
</script>