我遇到的这个问题有三个文件:
“本地销售”,“全球销售”和“模板”
销售文件的第1列和第2列是相同的,3每个都有不同的信息。必须将所有数据复制到“模板”中的工作表。
第1列和第2列必须复制到相同位置(第1列和第2列),第3列必须是本地销售文件中的第3列,第4列必须是全局销售文件中的第3列。和我一起到目前为止?我希望如此......
这个例程第一次运行时,一切顺利,花花公子。它迭代第一个源文件中的所有列,并将它们粘贴到模板上。但是当fileNumber = 2时(当它应该对第二个源文件执行相同操作时),标记的行声称“需要一个对象”。 这让我疯了,因为我看不出第一次工作的原因,而不是第二次工作的原因!
我知道使用像“激活”这样的命令是错误的,但这是我第一次使用VBA,这是我看到的第一件事。请怜悯:))
Sub OpenFiles(ByVal fileNumber)
If fileNumber = 1 Then
Dim localFile As Workbook
Set localFile = Application.Workbooks.Open("local sales.xls") ' here the path of "local sales.xls"
Dim templateFile As Workbook
Set templateFile = Application.Workbooks.Open("Template.xls") ' here the path of "Template.xls"
localFile.Sheets("Sheet1").Activate
Else
Dim globalFile As Workbook
Set globalFile = Application.Workbooks.Open("global sales.xls") ' here the path of "global sales.xls"
globalFile.Sheets("Sheet1").Activate
End If
Dim lastColumnOnSource, lastRow, lastColumnOnDestiny As Long
Dim textLastRow, textCol, areaToSelect, areaToPaste As String
lastColumnOnSource = (ActiveSheet.Cells(1, Columns.Count).End(xlToLeft).Column)
lastRow = ActiveSheet.UsedRange.Rows.Count
textLastRow = CStr(lastRow)
For currentColumnOnSource = 1 To lastColumnOnSource
If fileNumber = 1 Then
localFile.Sheets("Sheet1").Activate
Else
globalFile.Sheets("Sheet1").Activate
End If
columnAsLetter = ColumnLetter(currentColumnOnSource)
Let areaToSelect = columnAsLetter & "1:" & columnAsLetter & textLastRow
Range(areaToSelect).Select
Selection.Copy
' Moving to the template, to paste the data
templateFile.Sheets("Data").Activate ' HERE IS THE ERROR
lastColumnOnDestiny = ActiveSheet.Cells(1, Columns.Count).End(xlToLeft).Column
Dim cell1, cell2 As String
Dim cell2AsRange As Range
For currentColumnOnDestiny = 1 To lastColumnOnDestiny
' I take the first cell ("header") on the column and compare it until it's header
' matches the header on the column that is being copied and paste it there
Let cell1 = columnAsLetter & "1"
Let cell2 = ColumnLetter(currentColumnOnSource) & "1"
If Range(cell1).Value = Range(cell2).Value Then
' select the column that cell 2 belongs on, to paste in it
Let areaToPaste = cell1 & ":" & cell2
Range(areaToPaste).Select
Range(areaToPaste).PasteSpecial
Exit For
End If
Next
Next
Application.CutCopyMode = False
'Application.ActiveWorkbook.Save
End Sub
答案 0 :(得分:1)
正如Rich Holton指出的那样,除非templateFile
为1,否则你没有为fileNumber
赋值。因此,当你到达templateFile.Sheets("Data").Activate
语句时,它不知道是什么templateFile
是。
最简单的更改只是在TemplateFile
声明中添加If
作业。
Dim templateFile As Workbook
If fileNumber = 1 Then
Dim localFile As Workbook
Set localFile = Application.Workbooks.Open("local sales.xls") ' here the path of "local sales.xls"
Set templateFile = Application.Workbooks.Open("Template.xls") ' here the path of "Template.xls"
localFile.Sheets("Sheet1").Activate
Else
Dim globalFile As Workbook
Set globalFile = Application.Workbooks.Open("global sales.xls") ' here the path of "global sales.xls"
globalFile.Sheets("Sheet1").Activate
Set templateFile = Application.Workbooks("Template.xls") ' here the path of "Template.xls"
End If
这将解决您的直接问题,但我怀疑当您到达执行复制/粘贴的代码部分时,您将遇到问题。据我所知,您的第二个文件的详细信息将覆盖您从第一个文件中获得的内容,但您的问题不够明确,我无法为您修复该代码。 (您的问题只讨论了文件1中第3列到第3列的第3列,以及文件2中的第3列到第4列 - 但您的代码看起来似乎正在尝试处理比此更多的列。)
答案 1 :(得分:0)
您可以使用ADODB对Global Sales
和Template
工作簿进行SQL查询,然后将结果保存到SELECT
A.Field1 AS F1, A.Field2 AS F2, B.Field2 AS F3
FROM Table1 AS A
INNER JOIN Table2 AS B
工作簿中。
典型的INNER JOIN查询是:
SELECT
A.Field1 AS F1, A.Field2 AS F2, B.Field2 AS F3
FROM Table1 AS A
LEFT JOIN Table2 AS B
ON A.Field1 = B.Field1
UNION
SELECT
B.Field1 AS F1, A.Field2 AS F2, B.Field2 AS F3
FROM Table1 AS A
RIGHT JOIN Table2 AS B
ON A.Field1 = B.Field1
如果要组合来自两个源的数据,即使记录的某些字段为空,也可以尝试FULL JOIN查询。 Jet SQL不支持FULL JOIN,所以有一个解决方法,工会左右连接(注意非不同来源丢失重复):
Option Explicit
Sub JoinQuery()
Dim sGlobalDataPath As String
Dim sLocalDataPath As String
Dim sTemplatePath As String
Dim sGlobalDataSheet As String
Dim sLocalDataSheet As String
Dim sTemplateSheet As String
Dim sProvider As String
Dim sType As String
Dim sGlobalData As String
Dim sLocalData As String
Dim sConnection As String
Dim oTargetWorkbook As Workbook
Dim sQuery As String
Dim oConnection As Object
Dim oRecordset As Object
' Put your paths and sheet names below
' Set path to Global Sales source file
sGlobalDataPath = ThisWorkbook.Path & "\Global Sales.xlsx"
sGlobalDataSheet = "Sheet1"
' Set path to Local Sales source file
sLocalDataPath = ThisWorkbook.Path & "\Local Sales.xlsx"
sLocalDataSheet = "Sheet1"
' Set path to Local Sales source file
sTemplatePath = ThisWorkbook.Path & "\Template.xlsx"
sTemplateSheet = "Sheet1"
' Create connection string to open ADODB.Connection
GetConnOpts ThisWorkbook.FullName, sProvider, sType
sConnection = _
sProvider & _
"Data Source='" & ThisWorkbook.FullName & "';" & _
"Mode=Read;" & _
"Extended Properties=""" & sType & """;"
' Open connection
Set oConnection = CreateObject("ADODB.Connection")
oConnection.Open sConnection
' Create connection strings for source files
GetConnOpts sGlobalDataPath, sProvider, sType
sGlobalData = "[" & sGlobalDataSheet & "$] IN '" & sGlobalDataPath & "' " & _
"[" & sType & sProvider & "Mode=Read;Extended Properties=""HDR=YES;""] "
GetConnOpts sLocalDataPath, sProvider, sType
sLocalData = "[" & sLocalDataSheet & "$] IN '" & sLocalDataPath & "' " & _
"[" & sType & sProvider & "Mode=Read;Extended Properties=""HDR=YES;""] "
' Create INNER JOIN query string
sQuery = _
"SELECT " & _
"G.CustomerName, G.ContactName, G.Qty AS GlobalQty, L.Qty AS LocalQty " & _
"FROM " & _
"(SELECT * FROM " & sGlobalData & ") AS G " & _
"INNER JOIN " & _
"(SELECT * FROM " & sLocalData & ") AS L " & _
"ON G.ContactName = L.ContactName AND G.CustomerName = L.CustomerName;"
' Execute query
Set oRecordset = oConnection.Execute(sQuery)
' Open target workbook for output
Set oTargetWorkbook = Application.Workbooks.Open(sTemplatePath)
' Output resulting recordset
RecordsetToWorksheet oTargetWorkbook.Sheets(sTemplateSheet), oRecordset
' Save and close target workbook
oTargetWorkbook.Save
oTargetWorkbook.Close
' Close connection
oConnection.Close
End Sub
Sub GetConnOpts(sFile As String, sProvider As String, sType As String)
Select Case LCase(Mid(sFile, InStrRev(sFile, ".")))
Case ".xls"
sProvider = "Provider=Microsoft.Jet.OLEDB.4.0;"
sType = "Excel 8.0;"
Case ".xlsm"
sProvider = "Provider=Microsoft.ACE.OLEDB.12.0;"
sType = "Excel 12.0 Macro;"
Case ".xlsx", ".xlsb"
sProvider = "Provider=Microsoft.ACE.OLEDB.12.0;"
sType = "Excel 12.0;"
Case Else
sProvider = ""
sType = ""
End Select
End Sub
Sub RecordsetToWorksheet(oSheet As Worksheet, oRecordset As Object)
Dim i As Long
With oSheet
.Cells.Delete
For i = 1 To oRecordset.Fields.Count
.Cells(1, i).Value = oRecordset.Fields(i - 1).Name
Next
.Cells(2, 1).CopyFromRecordset oRecordset
.Cells.Columns.AutoFit
End With
End Sub
以下示例代码显示了如何完成INNER JOIN查询:
sQuery = ...
要使FULL JOIN使用以下代码替换字符串 ' Create simplified FULL JOIN query string
sQuery = _
"SELECT " & _
"G.CustomerName, G.ContactName, G.Qty AS GlobalQty, L.Qty AS LocalQty " & _
"FROM " & _
"(SELECT * FROM " & sGlobalData & ") AS G " & _
"LEFT JOIN " & _
"(SELECT * FROM " & sLocalData & ") AS L " & _
"ON G.CustomerName = L.CustomerName AND G.ContactName = L.ContactName " & _
"UNION " & _
"SELECT " & _
"L.CustomerName, L.ContactName, G.Qty AS GlobalQty, L.Qty AS LocalQty " & _
"FROM " & _
"(SELECT * FROM " & sGlobalData & ") AS G " & _
"RIGHT JOIN " & _
"(SELECT * FROM " & sLocalData & ") AS L " & _
"ON G.CustomerName = L.CustomerName AND G.ContactName = L.ContactName"
:
Global Sales.xlsx
我使用示例源文件Local Sales.xlsx
,Template.xlsx
和输出.xlsm
的文件测试了代码。所有这些文件都与Global Sales.xlsx
文件位于同一文件夹中,并带有上述代码。 Local Sales.xlsx
的内容是:
和Template.xlsx
:
INNER JOIN的输出.xlsb
为:
FULL JOIN的输出是:
您可以使用.xlsm
,.xls
,.xlsx
以及#include<pthread.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<ncurses.h>
const unsigned int NUM_OF_THREADS = 9;
typedef struct thread_data_s {
char *ptr;
int row_num;
} thread_data_t;
void report(const char *s,int w,int q);
void* row_check(void* data)
{
thread_data_t *my_data_ptr = data;
int j, flag;
flag=0x0000;
for(j = 0; j < 9; j++)
{
flag |= 1u << ( (my_data_ptr->ptr)[j] - 1 );
if (flag != 0x01FF){
report("row", my_data_ptr->row_num, j-1);
}
}
return NULL;
}
void report(const char *s,int w,int q)
{
printf("\nThe sudoku is INCORRECT");
printf("\nin %s. Row:%d,Column:%d",s,w+1,q+1);
getchar();
exit(0);
}
int main(int argc, char* argv[])
{
int i,j;
char arr1[9][9];
FILE *file = fopen(argv[1], "r");
if (file == 0)
{
fprintf(stderr, "failed");
exit(1);
}
int col=0,row=0;
int num;
while(fscanf(file, "%c ", &num) ==1) {
arr1[row][col] = num;
col++;
if(col ==9)
{
row++;
col = 0;
}
}
fclose(file);
int n;
thread_data_t data[NUM_OF_THREADS];
pthread_t tid;
pthread_attr_t attr;
for(n=0; n < NUM_OF_THREADS; n++)
{
data[n].ptr = &arr1[n][0];
data[n].row_num = n;
pthread_create(&tid, &attr, row_check, &data[n]);
}
for(n=0; n < NUM_OF_THREADS; n++)
{
pthread_join(tid, NULL);
}
return 0;
}
。