Пустые ячейки электронной таблицы Coldfusion

Я пытаюсь написать скрипт для загрузки листа Excel в базу данных, но я застрял на небольшой проблеме. Сценарий должен быть динамическим, чтобы его не нужно было изменять для загрузки другого листа Excel, просто лист должен соответствовать тому же соглашению, что и раньше.

Итак, выполнив:

<cfloop from="2" to="#sheet.rowcount#" index="row">

Это будет петля до конца строк, нет?

Поворот сюжета: мне нужно преобразовать пустые ячейки в «Н/Д»

Достаточно легко:

<cfif SpreadsheetGetCellValue(sheet,row,col) EQ "">
    <cfset SpreadsheetSetCellValue(sheet,"N/A",row,col) />
</cfif>

Проблема: из-за этого в моем фиктивном выводе появляются десятки строк (в конце, после того, как строки перестали содержать что-либо)

N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A

N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A
N/A

Очень много повторений. Лист имеет длину 56 строк, но это должно превышать 100. Я боюсь, что виновником является изменение пустых ячеек на «Н/Д», но я не уверен, как это исправить. Вот полный файл, и, к сожалению, я не могу показать таблицу Excel. Однако это 56 строк и 17 столбцов.

<cfspreadsheet action="read" src="derp.xlsx" name="sheet"> <!--- edit src --->
<!--- 17 columns wide 56 rows --->
<cfoutput>
    <cfloop from="2" to="#sheet.rowcount#" index="row">
        <cfloop from="1" to="17" index="col"> <!--- multi row selection (edit based on excel sheet) --->
        <cfif SpreadsheetGetCellValue(sheet,row,col) EQ "">
            <cfset SpreadsheetSetCellValue(sheet,"N/A",row,col) />
        </cfif>
        <cfoutput>#SpreadSheetGetCellValue(sheet,row,col)#</cfoutput><br />
        </cfloop>
        <br />
    </cfloop>
</cfoutput>

Как я могу преобразовать пустые ячейки в «Н/Д», чтобы сценарий не превосходил rowcount?


person Sterling Archer    schedule 06.01.2014    source источник
comment
Если вы cfdump sheet.rowcount сразу после тега cfspreadsheet, каково значение? Кроме того, если вы просто выведете значение строки во внешнем цикле, какое последнее число вы получите?   -  person Dan Bracuk    schedule 06.01.2014
comment
Он возвращает 100, и я не знаю, почему. Как я уже сказал, фактического контента всего 56 строк. Разве sheet.rowcount не делает то, что я думаю?   -  person Sterling Archer    schedule 06.01.2014
comment
вы можете добавить пробел в ячейку в строке 105 (или что-то после 100), а затем удалить его? Может быть, это чтение последней строки, в которой было редактирование?   -  person Matt Busche    schedule 06.01.2014
comment
@MattBusche, это сработало, но я понятия не имею, почему - проблема не в коде, а в том, как читается файл excel ??   -  person Sterling Archer    schedule 06.01.2014
comment
Я почти не использовал cfspreadsheet, но я бы сказал, что причина в этом. Это действительно хакерское решение, но вы можете вернуться назад от sheet.rowcount и проверить каждую ячейку, если она пуста, и как только вы найдете строку со значением, вы можете использовать ее как новую sheet.rowcount. Не отличное решение, но сработает.   -  person Matt Busche    schedule 06.01.2014
comment
Этот вопрос и ответ говорят, что он должен игнорировать пустые строки stackoverflow.com/questions/8058144/   -  person Matt Busche    schedule 06.01.2014
comment
Не могли бы вы опубликовать это как решение? Поскольку это решило мою проблему, вы заслуживаете галочки и моего плюса @MattBusche   -  person Sterling Archer    schedule 06.01.2014
comment
Он будет зацикливаться до конца строк, не так ли? Нет, не будет, потому что это логический номер строки, а не физический. Почему бы просто не прочитать лист в запросе, а затем выполнить его, как обычно? (Отказ от ответственности, я работаю над двумя вещами одновременно, поэтому, возможно, я пропустил что-то очевидное.. но я не уверен, что понял цель).   -  person Leigh    schedule 06.01.2014
comment
Я бы сказал, что следует использовать решение @Leigh, так как это имеет больше смысла в этом контексте.   -  person Matt Busche    schedule 06.01.2014
comment
Не могли бы вы показать мне пример? я не совсем понимаю   -  person Sterling Archer    schedule 06.01.2014
comment
@RUJordan - ЕСЛИ я правильно понимаю цель (прочитать значения из электронной таблицы), просто используйте action=read с атрибутом запроса. Что-то вроде <cfspreadsheet src="c:/path/to/file.xls" query="qData" sheet="1" /> прочитает значения на листе 1 и заполнит запрос значениями листа.   -  person Leigh    schedule 07.01.2014
comment
@Ли, спасибо за подсказку. Я попробую, но мне нужно вставить это в нормализованную базу данных, поэтому мне, возможно, придется сохранить вложенный цикл для чистого отношения indentitycol   -  person Sterling Archer    schedule 07.01.2014
comment
В этом случае я предлагаю загрузить содержимое электронной таблицы в промежуточную таблицу. Сделайте все необходимое в промежуточной таблице, а затем обновите реальные таблицы из промежуточной таблицы.   -  person Dan Bracuk    schedule 07.01.2014
comment
Да, я большой поклонник промежуточных таблиц вместо прямых вставок. Слишком легко шланг db с прямой вставкой. Промежуточные таблицы обеспечивают гораздо большую гибкость и лучшую обработку ошибок. Сделайте всю свою проверку, а затем вставьте все в одну транзакцию.   -  person Leigh    schedule 07.01.2014
comment
@RUJordan - Можете ли вы объяснить, какая связь identitycol существует с импортированными значениями? Возможно, есть более простой/надежный вариант. Но какой бы подход вы ни использовали, не используйте логическое количество строк, так как это не даст согласованных результатов. Кстати, я думаю, что первоначальная проблема была связана с использованием логического количества строк, в то же время добавлением строк с использованием SpreadsheetSetCellValue, которые изменяют количество строк по мере того, как вы зацикливались, приводит к неожиданным результатам.   -  person Leigh    schedule 07.01.2014
comment
У меня есть схема таблицы, например: states [id, statename, stateabbr], questions [id, questiontext], responses [id, responsetext] и QandA [id, sid, rid, qid, group] (есть еще столбцы, но сейчас они не имеют значения. В основном первый столбец — это список имен состояний, первая строка — это вопрос, и все смешанные строки - это ответы. Вопросы, ответы и идентификаторы состояний уникальны. Мой запрос гарантирует это. Таким образом, этот скрипт предназначен для загрузки новых вопросов без необходимости удаления всей базы данных и запуска заново каждый раз, когда необходимо загрузить новые данные.   -  person Sterling Archer    schedule 07.01.2014
comment
Как запрос обеспечивает уникальность? Пока кажется, что вы можете сделать то же самое с промежуточным столом. Обычно я вставляю все данные электронной таблицы в промежуточную таблицу. Затем используйте JOIN для различных таблиц, чтобы определить, что нового, а что изменилось. Затем легко добавить или обновить все записи с помощью нескольких запросов. Основная концепция обновления/удаления/добавления описана в варианте №2 здесь. Вам может понадобиться только добавить новую часть, но концепция та же. Поместите все в таблицу, а затем используйте SQL для проверки или обработки данных в одном пакете.   -  person Leigh    schedule 07.01.2014
comment
Как запрос обеспечивает уникальность? В частности, поскольку этот код не включен в OP, я пытаюсь лучше представить текущий процесс, чтобы дать более конкретные советы о том, как вы могли бы подойдите к нему с промежуточной таблицей ИЛИ измените текущий код.   -  person Leigh    schedule 07.01.2014
comment
Он использует запрос (псевдозапрос здесь), чтобы проверить, существует ли значение перед каждой вставкой (ЕСЛИ НЕ СУЩЕСТВУЕТ [значение в таблице] ВСТАВИТЬ значение в таблицу])   -  person Sterling Archer    schedule 07.01.2014
comment
IMO вставка, если она не существует... построить намного проще с промежуточной таблицей. Простое ОБНОВЛЕНИЕ (объединение по значению) идентифицирует существующие идентификаторы. Все, что не имеет идентификатора, является новым и получает INSERT. Идея состоит в том, чтобы использовать SQL на основе набора для обработки всего пакета, а не одной записи за раз. Тем не менее, вы все еще можете использовать циклический подход. Но я не вижу смысла использовать SpreadsheetGetCellValue. Просто прочитайте значения в запросе, затем прокрутите его и примените ту же логику. Единственная разница в том, что у вас есть все необработанные данные заранее, в одном запросе, вместо того, чтобы захватывать их по одной ячейке за раз.   -  person Leigh    schedule 07.01.2014