[英]C++ to VBA (Excel)
So, basically, in Excel, I have 4 columns of data (all with strings) that I want to process, and want to have the results in another column, like this (nevermind the square brackets, they just represent cells): 因此,基本上,在Excel中,我要处理4列数据(全部带有字符串),并希望将结果放在另一列中,如下所示(不要注意方括号,它们只是表示单元格):
Line Column1 Column2 Column3 Column4 Result
1: [a] [b] [k] [YES] [NO]
2: [a] [c] [l] [YES] [NO]
3: [b] [e] [] [YES] [NO]
4: [c] [e] [f] [NO] [NO]
5: [d] [h] [b] [NO] [NO]
6: [d] [] [w] [NO] [NO]
7: [e] [] [] [YES] [NO]
8: [j] [m] [] [YES] [YES]
9: [j] [] [] [YES] [YES]
10: [] [] [] [YES] [YES]
The process that I want the data to go through is this: 我希望数据通过的过程是这样的:
Assume that CheckingLine is the Line for which I currently want to calculate the value of Result, and that CurrentLine is any Line (except CheckingLine) that I am using to calculate the value of Result, at a given moment. 假定CheckingLine是我当前要为其计算Result值的行,并且CurrentLine是我在给定时刻用于计算Result值的任何行(CheckingLine除外)。
I have written the corresponding C++ code (which works) (and it could have been in any other language, C++ was just the one I was using at the moment) (and the code HAS NOT been optimized in any way, because it's purpose was to be AS CLEAR about its functionality AS POSSIBLE) (the table above is the actual result of running it): 我已经编写了相应的C ++代码(它可以工作)(并且可以用任何其他语言编写,C ++只是我目前使用的那种语言)(并且该代码没有以任何方式进行优化,因为它的目的是尽可能清楚地了解其功能)(上表是运行它的实际结果):
#include <iostream>
#include <string>
#include <vector>
std::vector<std::string> column1, column2, column3, column4, contentVector;
unsigned int location, columnsSize;
void InsertInVector(std::string Content)
{
if(Content == "")
{
return;
}
for(unsigned int i = 0; i < contentVector.size(); i++)
{
if(contentVector[i] == Content)
{
return;
}
}
contentVector.push_back(Content);
}
std::string VerifyCurrentVector(unsigned int Start)
{
std::string result = "";
if(contentVector.size() == 0)
{
result = "YES";
}
else
{
unsigned int nextStart = contentVector.size();
for(unsigned int i = 0; i < columnsSize; i++)
{
if(i != location)
{
for(unsigned int j = Start; j < nextStart; j++)
{
if(column1[i] == contentVector[j])
{
InsertInVector(column2[i]);
InsertInVector(column3[i]);
}
else if(column2[i] == contentVector[j])
{
InsertInVector(column1[i]);
InsertInVector(column3[i]);
}
else if(column3[i] == contentVector[j])
{
InsertInVector(column1[i]);
InsertInVector(column2[i]);
}
}
}
}
if(nextStart == contentVector.size())
{
for(unsigned int i = 0; i < columnsSize; i++)
{
if(i != location)
{
for(unsigned int j = 0; j < nextStart; j++)
{
if(column1[i] == contentVector[j] || column2[i] ==
contentVector[j] || column3[i] == contentVector[j])
{
if(column4[i] == "NO")
{
result = "NO";
return result;
}
}
}
}
}
result = "YES";
}
else
{
result = VerifyCurrentVector(nextStart);
}
}
return result;
}
std::string VerifyCell(unsigned int Location)
{
std::string result = "";
location = Location - 1;
if(column4.size() < Location)
{
result = "Error";
}
else if(column4[location] == "NO")
{
result = "NO";
}
else
{
contentVector.clear();
InsertInVector(column1[location]);
InsertInVector(column2[location]);
InsertInVector(column3[location]);
result = VerifyCurrentVector(0);
}
return result;
}
void SetUpColumns(std::vector<std::string> &Column1, std::vector<std::string> &Column2,
std::vector<std::string> &Column3, std::vector<std::string> &Column4)
{
if(Column4.size() > Column1.size())
{
for(unsigned int i = Column1.size(); i < Column4.size(); i++)
{
Column1.push_back("");
}
}
if(Column4.size() > Column2.size())
{
for(unsigned int i = Column2.size(); i < Column4.size(); i++)
{
Column2.push_back("");
}
}
if(Column4.size() > Column3.size())
{
for(unsigned int i = Column3.size(); i < Column4.size(); i++)
{
Column3.push_back("");
}
}
column1 = Column1;
column2 = Column2;
column3 = Column3;
column4 = Column4;
columnsSize = Column4.size();
}
int main()
{
std::vector<std::string> Column1, Column2, Column3, Column4;
Column1.push_back("a");
Column1.push_back("a");
Column1.push_back("b");
Column1.push_back("c");
Column1.push_back("d");
Column1.push_back("d");
Column1.push_back("e");
Column1.push_back("j");
Column1.push_back("j");
Column2.push_back("b");
Column2.push_back("c");
Column2.push_back("e");
Column2.push_back("e");
Column2.push_back("h");
Column2.push_back("");
Column2.push_back("");
Column2.push_back("m");
Column3.push_back("k");
Column3.push_back("l");
Column3.push_back("");
Column3.push_back("f");
Column3.push_back("b");
Column3.push_back("w");
Column4.push_back("YES");
Column4.push_back("YES");
Column4.push_back("YES");
Column4.push_back("NO");
Column4.push_back("NO");
Column4.push_back("NO");
Column4.push_back("YES");
Column4.push_back("YES");
Column4.push_back("YES");
Column4.push_back("YES");
SetUpColumns(Column1, Column2, Column3, Column4);
std::cout << "Line\t" << "Column1\t" << "Column2\t" << "Column3\t" << "Column4\t" <<
std::endl;
for(unsigned int i = 0; i < Column4.size(); i++)
{
std::cout << i + 1 << ":\t" << "[" << column1[i] << "]\t[" << column2[i] <<
"]\t[" << column3[i] << "]\t[" << column4[i] << "]\t[" << VerifyCell(i + 1)
<< "]" << std::endl;
}
return 0;
}
So, after this lengthy explanation, what I want to know is this: 因此,经过冗长的解释,我想知道的是:
Is there any way to do this in Excel's VBA? 在Excel的VBA中有什么方法可以做到这一点?
Yes, you can surely do this with VBA, it is a complete and powerful programming language 是的,您肯定可以使用VBA进行此操作,它是一种完整而强大的编程语言
(or even better, in plain Excel without VBA)? (甚至更好,在没有VBA的纯Excel中)?
Nope. 不。 The calculation seems too complicated to fit with Excel formulae without any VBA code. 该计算似乎过于复杂,无法与没有任何VBA代码的Excel公式配合使用。
If not, how can I have my code (which I can easily translate to another C-like language and/or optimise) get the data from, and deliver the results to, Excel? 如果不是,我如何让我的代码(可以轻松地将其转换为另一种类似于C的语言和/或优化)将其从Excel中获取数据并将结果传递给Excel?
You can access Excel from C++ in many ways. 您可以通过多种方式从C ++访问Excel。 Using ATL is one of them. 使用ATL是其中之一。 another, easier way would be to import/export your Excel file in CSV format, which is easy to parse and write from C++. 另一种更简单的方法是以CSV格式导入/导出Excel文件,该文件易于从C ++解析和编写。 Also consider C#, it has complete COM inter-operability to access office components. 还考虑C#,它具有完全的COM互操作性以访问办公组件。
Ok, if you like to "whipped the code in a rush" then you'll love VBA, next time please try to ask a more specific question. 好的,如果您想“匆忙处理代码”,那么您会爱上VBA的,下次请尝试提出更具体的问题。 Based on code and comments @MikeAscended you're a relatively good programmer, with a grasp of functions/recursion, variable/parameters, conditions, loops, data structures, etc. Re: " I have only touched VBA once in my life and ran away from it" My intent is to get you started and give you syntax here not necessarily a working solution. 根据代码和注释@MikeAscended,您是一个相对不错的程序员,具有函数/递归,变量/参数,条件,循环,数据结构等方面的理解。Re:“我一生只接触过VBA,然后运行远离它”的目的是让您入门并在这里提供语法,不一定是可行的解决方案。 I'm happy to answer any further specific questions you may continue to have. 我很高兴回答您可能还会遇到的其他任何具体问题。
Strategy-wise , I recommend plain VBA which is easy to use in Excel. 从策略角度考虑 ,我建议在Excel中易于使用的纯VBA。 Obviously your problem can be solved in many ways including formulas, however VBA is a powerful tool that any programmer will benefit from using. 显然,您的问题可以通过许多方法解决,包括公式,但是VBA是一个功能强大的工具,任何程序员都可以从中受益。
Code-wise , To start access the editor from Excel press [Alt-F11], or from Design Mode insert and double-click an ActiveX button. 按代码编写,要从Excel开始访问编辑器,请按[Alt-F11],或从“设计模式”插入并双击ActiveX按钮。 To run a macro press [Alt-F8], or in VBA click the green play button. 要运行宏,请按[Alt-F8],或在VBA中单击绿色的播放按钮。
One last note, if you want those line numbers in column 1 in excel then yours will become Column 2-5 or BF. 最后一点,如果您希望在excel的第1列中使用这些行号,则您将成为第2-5列或BF。 I'm assuming you'll use the row numbers in excel so that Column 1 is A, but row 1 will still have titles, so you are staring your data on row 2. 我假设您将使用excel中的行号,以使第1列为A,但第1行仍将具有标题,因此您将数据盯在第2行。
sub processResults_Col5()
' Run This Script as Main()
dim rowCount as long, i as long 'rowCount = columnsSize
with sheets(1)
.Range("A1:D1") = Array("a", "b", "k", "YES")
' finish init here
' SetUpColumns not necessary in excel
if .cells(2,1).value <> "" then 'do not use .end(xldown) if data is missing
rowCount = .cells(1,1).end(xldown).row
for i = 1 to rowCount
.cells(i,5) = verifyCell(i + 1, rowCount)
next i
endif 'space will be added :p
end with
end sub
function verifyCell(rowLocation as long, size as long, optional wSh as excel.worksheet) as string
' the rest should be easy for you to figure out based on C-code
with wSh
if wsh is nothing then set wsh = activesheet 'let VBA capitalize stuff so you know you typed it correctly
if size < rowlocation then
verifyCell = "Error" 'the function name is the return value
'msgbox "Error" ' you can uncomment this line to see error
elseif cells(rowLocation, 4).value = "NO" then
cells(rowLocation, 5) = "NO" 'set result
else
call InsertInVector(rowLocation) 'CheckingLine
' edit the current rowLocation with for loops
verifyCell = VerifyCurrentVector(0) 'whatever you're doing here
endif
end with
end function
sub InsertInVector()
end sub
sub VerifyCurrentVector() 'function returns a value
end sub
Some tips: 一些技巧:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.