powered by simpleCommunicator - 2.0.31     © 2024 Programmizd 02
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
19 сообщений из 19, страница 1 из 1
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
    #39586914
verter
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Делаю XSL-преобразование исходного XML для выгрузки его в Excel.
Использую стандартную XML-схему для этого:

Код: html
1.
2.
3.
4.
5.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel">
...
</xsl:stylesheet>



Вызываю Excel-функцию суммирования в формуле для ячейки вот таким образом:

Код: html
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel">
...
<xsl:template match="/">
<html xmlns="http://www.w3.org/TR/REC-html40"
xmlns:o="urn:schemas-microsoft-com:office:office" 
xmlns:x="urn:schemas-microsoft-com:office:excel" >
...
  <td class="xl788" style='border-left:none' x:num="" x:fmla="">
     <xsl:attribute name="x:fmla">=SUM(A1:A5)</xsl:attribute>
     <!--xsl:attribute name="x:fmla">=SUM(R10C5:R<xsl:value-of select="9+count(ROW)-1"/>C5)</xsl:attribute-->
  </td>
...
</html>
</xsl:template>
</xsl:stylesheet>



и всё прекрасно работает.

но возникла необходимость использовать стиль адресации ячеек не буквено-цифровой A1, а цифровой R1C1.

Пытаюсь поменять:

Код: html
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel">
...
<xsl:template match="/">
<html xmlns="http://www.w3.org/TR/REC-html40"
xmlns:o="urn:schemas-microsoft-com:office:office" 
xmlns:x="urn:schemas-microsoft-com:office:excel" >
...
  <td class="xl788" style='border-left:none' x:num="" x:fmla="">
     <xsl:attribute name="x:fmla">=SUM(R1C1:R5C1)</xsl:attribute>
  </td>
...
</html>
</xsl:template>
</xsl:stylesheet>



Не понимает. Эксель даёт ошибку.

Тогда в XSLT я меняю стиль адресации на R1C1 указывая:

Код: html
1.
2.
3.
...
<x:RefModeR1C1/>
...



и в Excel действительно меняется стиль адресации, но всё-равно выдаётся ошибка - не понимает формулу в формате R1C1.


Понимаю, что вопрос сложный, но вдруг кто сталкивался?
...
Рейтинг: 0 / 0
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
    #39587154
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
verterПонимаю, что вопрос сложный, но вдруг кто сталкивался?Создаете лист с формулой в Экселе, сохраняете в XML и смотрите, что получилось. Потом пишете соответствующую XSL. Если возникают трудности, тогда публикуете кусок целевого XML здесь
...
Рейтинг: 0 / 0
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
    #39587155
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здесь у Вас ошибка в том, что Вы атрибут определяете дважды
verter
Код: javascript
1.
2.
3.
<td class="xl788" style='border-left:none' x:num="" x:fmla="">
     <xsl:attribute name="x:fmla">=SUM(R1C1:R5C1)</xsl:attribute>
  </td>
...
Рейтинг: 0 / 0
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
    #39587159
verter
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,
я, конечно, так и сделал - сохранил в XML лист Экселя с формулой в стиле R1C1 и с включённым цифровым режимом R1C1.
Но к моему удивлению в XML в формуле всё-равно стоял стиль A1.
...
Рейтинг: 0 / 0
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
    #39587167
verter
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_Здесь у Вас ошибка в том, что Вы атрибут определяете дважды
verter
Код: javascript
1.
2.
3.
  <td class="xl788" style='border-left:none' x:num="" x:fmla="">
     <xsl:attribute name="x:fmla">=SUM(R1C1:R5C1)</xsl:attribute>
  </td>



да, убрал лишнее, но это не повлияло на результат - Ошибка в формуле ячейки.
...
Рейтинг: 0 / 0
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
    #39587195
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
verter_Vasilisk_Здесь у Вас ошибка в том, что Вы атрибут определяете дважды
пропущено...


да, убрал лишнее, но это не повлияло на результат - Ошибка в формуле ячейки.напишите формулу от руки, чтобы работала, сохраните и посмотрите отличия.
...
Рейтинг: 0 / 0
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
    #39587295
verter
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Antonariyverterпропущено...


да, убрал лишнее, но это не повлияло на результат - Ошибка в формуле ячейки.напишите формулу от руки, чтобы работала, сохраните и посмотрите отличия.

делал уже так. всё-равно даже если сохраняю в R1C1, то в сохранённом XSLT получается A1.
...
Рейтинг: 0 / 0
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
    #39587359
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
verterесли сохраняю в R1C1, то в сохранённом XSLT получается A1.Значит R1C1 это вопрос чисто отображения. А внутри идет сохранение всегда в виде A1
...
Рейтинг: 0 / 0
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
    #39587533
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_verterесли сохраняю в R1C1, то в сохранённом XSLT получается A1.Значит R1C1 это вопрос чисто отображения. А внутри идет сохранение всегда в виде A1вообще-то нет, у меня были документы с обоими вариантами адресации. не понятно, почему у ТСа не работает. может версия офиса виновата?
...
Рейтинг: 0 / 0
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
    #39588914
verter
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
решил сделать просто перечислением букв в шаблоне, вот так суммирую данные в ячейках A1:A5 и B1:B5:

Код: html
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
<xsl:template name="printColumnLetter">
  <xsl:param name="cnum"/> 
    <xsl:if test="$cnum = 1"><xsl:value-of select="concat('A', '')"/></xsl:if>
    <xsl:if test="$cnum = 2"><xsl:value-of select="concat('B', '')"/></xsl:if>
    ...
</xsl:template>

<xsl:template name="printTotal">
  <xsl:param name="idx"/>  
    <xsl:if test="$idx > 0">
      <xsl:call-template name="printTotal">
        <xsl:with-param name="idx" select="$idx - 1"/>
      </xsl:call-template>    
      <td x:num=''>
        <xsl:attribute name="x:fmla">=SUM(<xsl:call-template name="printColumnLetter"><xsl:with-param name="cnum" select="$idx"/></xsl:call-template>1:<xsl:call-template name="printColumnLetter"><xsl:with-param name="cnum" select="$idx"/></xsl:call-template>5)</xsl:attribute>
      </td>
    </xsl:if>
</xsl:template>

<xsl:call-template name="printTotal">
  <xsl:with-param name="idx" select="2"/>      
</xsl:call-template>



и это работает. но надо распространить это решение на случай когда буквы в колонках закончатся и пойдут AA, AB, ...
а потом и BA, BB, ...
для этого я написал ещё вот такой шаблон:

Код: html
1.
2.
3.
4.
5.
6.
7.
<xsl:template name="printPreLetter">
  <xsl:param name="nmb"/>
    <xsl:if test="$nmb &lt;= 26"><xsl:value-of select="concat('', '')"/></xsl:if> 
    <xsl:if test="$nmb &gt; 26*1"><xsl:value-of select="concat('A', '')"/></xsl:if>
    <xsl:if test="$nmb &gt; 26*2"><xsl:value-of select="concat('B', '')"/></xsl:if>
    ...
</xsl:template>



и пытаюсь его вызывать в шаблоне, который выдаёт буквы колонки:

Код: html
1.
2.
3.
4.
5.
6.
<xsl:template name="printColumnLetter">
  <xsl:param name="cnum"/> 
    <xsl:if test="$cnum = 1"><xsl:value-of select="concat(<xsl:call-template name="printPreLetter"><xsl:with-param name="nmb" select="$cnum"/></xsl:call-template>, 'A', '')"/></xsl:if>
    <xsl:if test="$cnum = 2"><xsl:value-of select="concat(<xsl:call-template name="printPreLetter"><xsl:with-param name="nmb" select="$cnum"/></xsl:call-template>, 'B', '')"/></xsl:if>
    ...
</xsl:template>



но получаю ошибку.
помогите, пожалуйста, новичку разобраться. Как правильно в этом случае вызвать шаблон?
...
Рейтинг: 0 / 0
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
    #39589296
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вопрос номер раз. Зачем вот эта порнография?
verter
Код: xml
1.
concat('B', '')

чем не угодило
Код: xml
1.
<xsl:value-of select="'A'"/>

?

Вопрос номер два. Судя по каскаду
Код: xml
1.
<xsl:if

о существовании
Код: xml
1.
<xsl:choose>

Вы не догадываетесь?

Зачем вызывать несколько раз
verter
Код: html
1.
<xsl:call-template name="printPreLetter"><xsl:with-param name="nmb" select="$cnum"/></xsl:call-template>


когда можно это сделать лишь однажды и сохранить значение в переменной мне тоже непонятно

Ну и вот эта запись - это да. Вы сами ее разберете через пару месяцев?
verter
Код: html
1.
<xsl:attribute name="x:fmla">=SUM(<xsl:call-template name="printColumnLetter"><xsl:with-param name="cnum" select="$idx"/></xsl:call-template>1:<xsl:call-template name="printColumnLetter"><xsl:with-param name="cnum" select="$idx"/></xsl:call-template>5)</xsl:attribute>



Итого, с учетом всего, получаем
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
  <xsl:template name="printPreLetter">
    <xsl:param name="nmb"/>
    <xsl:choose>
      <xsl:when test="$nmb &lt;= 26"><xsl:value-of select="''"/></xsl:when> 
      <xsl:when test="$nmb &gt; 26*1"><xsl:value-of select="'A'"/></xsl:when>
      <xsl:when test="$nmb &gt; 26*2"><xsl:value-of select="'B'"/></xsl:when>
      ...
      <xsl:otherwise>
        ........
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <xsl:template name="printColumnLetter">
    <xsl:param name="cnum"/>
    <xsl:variable name="preLetter">
      <xsl:call-template name="printPreLetter">
        <xsl:with-param name="nmb" select="$cnum"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:choose>
      <xsl:when test="$cnum = 1"><xsl:value-of select="concat($preLetter, 'A')"/></xsl:when>
      <xsl:when test="$cnum = 2"><xsl:value-of select="concat($preLetter, 'B')"/></xsl:when>
    </xsl:choose>
  </xsl:template>
  
  <td x:num=''>
    <xsl:attribute name="x:fmla">=SUM(
      <xsl:call-template name="printColumnLetter">
        <xsl:with-param name="cnum" select="$idx"/>
      </xsl:call-template>
      1:
      <xsl:call-template name="printColumnLetter">
        <xsl:with-param name="cnum" select="$idx"/>
      </xsl:call-template>
      5)
    </xsl:attribute>
  </td>


А теперь оптимизируем. Прежде всего, поднимем еще читабельность для блока <td x:num=''>
Код: xml
1.
2.
3.
4.
5.
6.
<xsl:variable name="column">
  <xsl:call-template name="printColumnLetter">
    <xsl:with-param name="cnum" select="$idx"/>
  </xsl:call-template>
</xsl:variable>
<td x:num='' x:fmla="{concat('SUM(', $column, '1:', $column, '5)')}"/>


Далее, все Ваши шаблоны - это всего-лишь попытка отобразить числа 1, 2, 3 на буквы A, B, C. Куча <xsl:if, это, конечно здорово, тем более при наличии буфера обмена, но почему бы не сделать все по человечески?
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
<xsl:template name="numToLetter">
  <xsl:param name="num"/>
  <xsl:variable name="mask" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
  <xsl:value-of select="substring($mask, $num, 1)"/>
</xsl:template>

<xsl:template name="printColumnLetter">
  <xsl:param name="cnum"/>
  <xsl:variable name="preLetter">
    <xsl:call-template name="numToLetter">
      <xsl:with-param name="num" select="$cnum div 26"/>
    </xsl:call-template>
  </xsl:variable>
  <xsl:variable name="letter">
    <xsl:call-template name="numToLetter">
      <xsl:with-param name="num" select="$cnum mod 26"/>
    </xsl:call-template>
  </xsl:variable>
  <xsl:value-of select="concat($preLetter, $letter)"/>
</xsl:template>

...
Рейтинг: 0 / 0
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
    #39589349
verter
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,
огромное спасибо за помощь!

Я на все вопросы могу ответить так - у меня совсем мало опыта в этом деле, т.е. я новичёк, поэтому пишу пока плохой код, т.к. не знаю просто многих вещей. Про choose, конечно, знал, но посчитал, что с choose надо на 1 строку больше кода, но это же не суть.
Сейчас перепишу всё в соответствии с вашими исправлениями.
...
Рейтинг: 0 / 0
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
    #39589418
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
verterс choose надо на 1 строку больше кода, но это же не суть.С choose сравнения прекращаются при выполнении первого условия, а с набором if идет последовательный перебор всех вариантов
...
Рейтинг: 0 / 0
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
    #39589422
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ошибка. Вместо
_Vasilisk_
Код: xml
1.
<xsl:with-param name="num" select="$cnum div 26"/>

должно быть
Код: xml
1.
<xsl:with-param name="num" select="floor($cnum div 26)"/>
...
Рейтинг: 0 / 0
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
    #39590197
verter
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,
да, с floor я тоже сразу заметил, т.к. div - это не div, а просто деление.
кроме этого нужно 1 отнять ещё.
но есть и ещё одна ошибка 26 mod 26 = 0, а нам нужно 26, поэтому окончательный вариант будет такой:

Код: html
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
<xsl:template name="printColumnLetter">
  <xsl:param name="cnum"/>
  <xsl:variable name="preLetter">
    <xsl:call-template name="numToLetter">
      <xsl:with-param name="num" select="floor(($cnum - 1) div 26)"/>
    </xsl:call-template>
  </xsl:variable>
  <xsl:variable name="letter">
    <xsl:variable name="res">
      <xsl:value-of select="$cnum mod 26"/>
    </xsl:variable> 
    <xsl:variable name="nmb">
      <xsl:choose>
        <xsl:when test="$res = 0"><xsl:value-of select="26"/></xsl:when>
        <xsl:otherwise><xsl:value-of select="$res"/></xsl:otherwise>
      </xsl:choose>
    </xsl:variable>
    <xsl:call-template name="numToLetter">
      <xsl:with-param name="num" select="$nmb"/>
    </xsl:call-template>
  </xsl:variable>
  <xsl:value-of select="concat($preLetter, $letter)"/>
</xsl:template>
...
Рейтинг: 0 / 0
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
    #39590199
verter
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_verterс choose надо на 1 строку больше кода, но это же не суть.С choose сравнения прекращаются при выполнении первого условия, а с набором if идет последовательный перебор всех вариантов

это да, но я посчитал, что например

Код: html
1.
2.
<xsl:if test="$res = 0"><xsl:value-of select="26"/></xsl:if> 
<xsl:if test="$res &gt; 0"><xsl:value-of select="$res"/></xsl:if-->



короче чем:

Код: html
1.
2.
3.
4.
5.
  
<xsl:choose>
  <xsl:when test="$res = 0"><xsl:value-of select="26"/></xsl:when>
  <xsl:otherwise><xsl:value-of select="$res"/></xsl:otherwise>
</xsl:choose>
...
Рейтинг: 0 / 0
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
    #39590474
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
verterпоэтому окончательный вариант будет такой:Опять все усложнили
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
<xsl:template name="printColumnLetter">
  <xsl:param name="cnum"/>
  <xsl:variable name="local_num" select="$cnum - 1"/>
  <xsl:variable name="preLetter">
    <xsl:call-template name="numToLetter">
      <xsl:with-param name="num" select="floor($local_num div 26)"/>
    </xsl:call-template>
  </xsl:variable>
  <xsl:variable name="letter">
    <xsl:call-template name="numToLetter">
      <xsl:with-param name="num" select="($local_num mod 26) + 1"/>
    </xsl:call-template>
  </xsl:variable>
  <xsl:value-of select="concat($preLetter, $letter)"/>
</xsl:template>
...
Рейтинг: 0 / 0
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
    #39590475
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
verterкороче чем:А написать в одну строчку еще короче. Только потом фиг, что разберешь
...
Рейтинг: 0 / 0
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
    #39590830
verter
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,
ещё раз большое спасибо!
я думаю эта ветка будет полезна и для других.
...
Рейтинг: 0 / 0
19 сообщений из 19, страница 1 из 1
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]